I have created a new native module in my React Native application (It's called RCTAVAudioSessionModule).
When looking in the AppDelegate I found this code snippet:
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
NSArray<id<RCTBridgeModule>> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge];
// If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here!
return extraModules;
}
I want to add my native module to the extraModules array.
I tried to do something like that:
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
NSArray<id<RCTBridgeModule>> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge];
// If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here!
return [extraModules arrayByAddingObject:(RCTAVAudioSessionModule.new)];
}
However, when I try to call a method from module I get an error that says:
TypeError: null is not an object (evaluating 'RCTAVAudioSessionModule.getCurrentRoute')
How can I correctly add my native module and use it on iOS?
Related
I've used dispatch in my component like following but I get the error modifySeatMap is not defined .But I do have modifySeatMap function defined in one of my action files. Why is this showing modifySeatMap not defined yet?
const dispatch = useDispatch();
const changeStatus=(seat)=>{
console.log("change status called with seat",seat)
seat.status="selected"
dispatch(
modifySeatMap(props.seatMap))
}
I'm attaching the screenshot of the directory structre and the method inside the action here
Why is modifySeatMap undefined here?
From your code, I do not see any issues.
I expect the issue is in how you apply your middleware.
It should look something like this.
export default store = createStore(rootReducer, applyMiddleware(thunk))
I'm scanning QR code containing FB Dynamic Link inside from withing my app. I get something like this https://myapp.page.link/S8rq8wTHFE1KYj8D8.
The question is how do I resolve the underlying URL/link that was used when this link was created?
// add import
import dynamicLinks from '#react-native-firebase/dynamic-links';
// use this line in your code
// `deepLink` is your `https://myapp.page.link/S8rq8wTHFE1KYj8D8`
const resolvedLink = await dynamicLinks().resolveLink(deepLink);
Docs: https://rnfirebase.io/reference/dynamic-links#resolveLink
I'm a little confused. I just did these two tutorials to start writing my own native modules in Swift:
https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-1-modules-9bb8d054db03
https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-2-ui-components-907767123d9e
The first one is a viewless module and is imported like this:
const { Module } = NativeModules;
The second is a native component with a view and is imported like this:
const ImageBlendView = requireNativeComponent('ImageBlendView')
Are these in some way interchangeable or does the existence or non-existence of a UI View make a fundamental difference?
I have built a custom video player component in React using video js. I am trying to implement a context menu using videojs-contextmenu and videojs-contextmenu-ui. However when I try to initialize the plugin, I get the following error.
Message: Uncaught TypeError: this.playerInstance.contextmenuUI is not a function - URL: webpack-internal:///375 - Line: 116 - Column: 27 - Error object: {}
Since I have customised the components, how do I initialize the plugin. I have imported videojs and only after that have I imported videojs-contextmenu and videojs-contextmenu-ui.
import videojs from 'video.js';
import SmartModeToggleMenuButton from './SmartModeToggleMenuButton';
import 'videojs-contextmenu';
import 'videojs-contextmenu-ui';
const Player = videojs.getComponent('Player');
videojs.registerComponent('smartModeToggleMenuButton', SmartModeToggleMenuButton);
class SmartModePlayer extends Player {
constructor(tag, options,ready) {
super(tag,options, ready);
//some custom code
}
}
videojs.registerComponent('SmartModePlayer', SmartModePlayer);
export default SmartModePlayer;
Then, elsewhere I use the SmartModepLayer as follows:
this.playerInstance = new SmartModePlayer(this.kaalRecordingPlayer, options , function () {});
this.playerInstance.contextmenuUI();
How do I correctly use videojs-conetxtmenu-ui plugin when using in a custom component as above.
I had to specifically call these 2 lines:
videojs.registerPlugin('contextmenu', VjsContextMenu);
videojs.registerPlugin('contextmenuUI', VjsContextMenuUI);
I have a react native application I am building, and for part of it I have implemented my own custom module (in this case a webview). I have it set up and everything works fine, until I render two of the same modules on the same screen.
Once I have had two of the same modules on the same screen, the code in Objective-C which calls the onChange method back to javascript no longer executes and I can longer longer communicate with my module through Javascript.
I've noticed that each instance of my module has a tag or something like that, but I am not sure what I should do to fix this.
Update
Basically I have added some code and I can see that the issue is when the new module is added to the screen, it overrides the callbacks for the previous module. Once the new modules leaves the screen, the callbacks in Objective-C are still "focused" on the most recently rendered module...
Might this have something to do with?
ReactNative.findNodeHandle(this.refs[WEB_VIEW]);
Edit
I have been looking over some open source code and I think I have narrowed down the problem. Basically my module consists of a WebView and a WebViewManager. The WebViews are pretty simple and just display the contents of the web and such, and the manager is responsible for controlling their behavior.
When I want to call a method on the module from React Native, I can do so by calling the method on the WebViewManager like this:
scrollToTop() {
RNTWebViewManager.scrollToTop();
}
In which the manager will then call the corresponding method in Objective-C. However, it seems that when I have more than one instance of a WebView on screen at a time, the manager doesn't know which instance to call, and resorts to calling the most recent instance that was placed on screen.
In the open source project I see that they do something by passings refs around and getting the specific view tags, which is then used by the manager to call on the correct instance of their WebViews, but I am still trying to figure out how to implement this.
Here is the link below for the project I was looking at:
https://github.com/CRAlpha/react-native-wkwebview
Ok so after quite some time and research I have finally figured out the solution. Basically it has to do with making sure the right component is being called from React Native and Objective-C. For example in your react native component you have a function:
executeJavascript(tag,js) {
RNTWebViewManager.executeJavascript(tag,js);
}
And then in your Objective-C implementation of RNTWebViewManager you could have something like this:
RCT_EXPORT_METHOD(executeJavascript:(nonnull NSNumber *)reactTag with:(NSString *)js)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNWebView *> *viewRegistry) {
RNWebView *view = viewRegistry[reactTag];
[view evaluateJavaScript:js completionHandler:^(id _Nullable result, NSError * _Nullable error) {
if (result == nil) { result = #""; }
id outputError = (error) ? error.description : #"";
view.onChange(#{ #"result" : result, #"error": outputError, #"type" : #"javascript" });
}];
}];
}
Notice how the executeJavascript function takes a tag, that is a reference to the current view you are trying to invoke that method on. So basically all you need to do is pass that tag number whenever you want to perform a method on a specific instance, which you can get like so:
getTag() {
return ReactNative.findNodeHandle(this.refs['RNWebView']);
}
Where in this case the ref is 'RNWebView', which would give me back the right tag which I could then use to call the function. Hope I did a decent job of explaining this.