Package for view manager and register in MainApplication.java
You need to create the react package for the view manager class. For that create new java class that implements ReactPackage interface as below.
Subsequently mention this package in ‘getPackages’ method of ’MainApplication.java’ class.
Native module integration with iOS
Native custom view and bridging header file and SwiftComponetModule.m file
Likewise create new swift file with custom view design of ‘TextField’,’Label’ and ‘Button’ in native side and initialise swift file with iOS code and create update method and button click event for the view.
class NativeView: UIView {
var onChange: RCTBubblingEventBlock?
let label = UILabel()
let txtField = UITextField()
var btn:UIButton!
private var _nativeText:String?
var nativeText: String? {
set {
_nativeText = newValue
}
get {
return _nativeText
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addCustomView()
}
required init(coder aDecoder: NSCoder) {
fatalError(“init(coder:) has not been implemented”)
}
func addCustomView() {
txtField.frame = CGRect(x: 32, y: 30, width: 300, height: 30)
txtField.placeholder = “Enter Text”
txtField.isUserInteractionEnabled = true
label.frame = CGRect(x: 32, y: 90, width: 200, height: 30)
label.textColor = UIColor.gray
label.text = “Text”
btn = UIButton.init(type: .custom)
btn.frame = CGRect(x: 32, y: 120, width: 300, height: 30)
btn.backgroundColor=UIColor.gray
btn.setTitle(“Click Here”, for: UIControlState.normal)
btn.addTarget(self, action: #selector(pressButton(_:)), for:
.touchUpInside)
self.addSubview(txtField)
self.addSubview(label)
self.addSubview(btn)
}
func updateValue() {
label.text = nativeText as? String
}
@objc func pressButton(_ sender: UIButton){
if onChange != nil {
onChange!([“nativeObject”: txtField.text!])
}
}
}
So once created swift class in addition create bridging header file which will help to communicate between Swift code and Objective C code as written below in header file.
React Native will not export any function of class you have created to React Javascript unless explicitly done. For this you need to use RCT_EXPORT_METHOD() macros. This will exposed all property of class created to Javascript object. RCT_EXPORT_METHOD support all type of conversion like(NSString to string, NSInteger float double, CGFloat NSNumber to number, BOOL to boolean, NSArray to array, NSDictionary to key and value of object of other types, RCTResponseSenderBlock to function). As a result update code of SwiftComponetModule.m is as below.
@interface RCT_EXTERN_MODULE(SwiftComponentManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(nativeText, NSString)
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
RCT_EXTERN_METHOD(updateValueViaManager:(nonnull NSNumber *)node)
end
View manager for custom view
Firstly create RCTViewManager class. The RCTViewManager class is the root most of React Native class in iOS which has ability to behave as Objective C object. You have to pass class to function @objc before inherited from RCTViewManager which makes this class available to Objective C.
@objc (SwiftComponentManager)
class SwiftComponentManager: RCTViewManager {
override func view() -> UIView! {
return NativeView()
}
}
Finally below function needed to update view using manager class.
func updateValueViaManager(_ node:NSNumber) {
DispatchQueue.main.async {
let myLabel = self.bridge.uiManager.view(forReactTag: node) as! NativeView
myLabel.updateValue()
}
}
Implementation with React Native
React custom component same as native custom view
After that, create same custom view in React Native like you have created for iOS and Android. For this let’s create React Component using TextInput, Text and TouchableOpacity as written in below code snippets.
While button clicked in React Component it will update Native view using below code.
onButtonClick = () => {
const { inputText } = this.state;
this.setState({
nativeText: inputText,
});
setTimeout(() => {
if (Platform.OS === ‘ios’) {
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(this.mySwiftComponentInstance),
UIManager.SwiftComponent.Commands.updateValueViaManager,
[]
);
}
}, 300);
};
Bridge to connect react native with native code and configure both component in App.js
In addition you need to create the bridge for the component to communicate with each other.
import { requireNativeComponent, View } from ‘react-native’;
const NativeComponent = requireNativeComponent(‘SwiftComponent’);
Hence, onChange function props called when native button click and the handler of that function at React Native side receive the value in event.nativeEvent
onSetText = event => {
this.setState({ textData: event.nativeEvent.nativeObject });
};
Finally you have your own native module integrated with your React Native application. With the help of native module you can implement any Native features which are not available in React Native or code you have developed before and want to reuse it.