I'm trying to handle both of Twitter and deep link in openURL, using ReactNative.
The code below does not work, ending up go into if (LinkingHandled) even when handling Twitter.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
bool TwitterHandled = [[Twitter sharedInstance] application:application openURL:url options:options];
bool LinkingHandled =[RCTLinkingManager application:application openURL:url options:options];
if (TwitterHandled) {
return TwitterHandled;
}
if (LinkingHandled) {
return LinkingHandled;
}
return NO;
}
What is wrong with this? I'm new to ObjC.
Use } else if { so only Twitter goes if it gets handled, and 'linking' will only go if TwitterHandled is NO and LinkingHandled is YES.
This can be simplified into one expression:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
return [Twitter.sharedInstance
application:application
openURL:url options:options] ||
[RCTLinkingManager
application:application
openURL:url
options:options];
}
Switch to Swift if you can. 🙂
Related
I am integrating Fitbit into my react-native app and there is a piece of code that I should add to my AppDelegate.m:
#import "RCTLinkingManager.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [RCTLinkingManager
application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
but I already have that set up that handles FB login and firebase linking and maybe something else:
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options]) {
return YES;
}
if ([RCTLinkingManager application:app openURL:url options:options]) {
return YES;
}
return NO;
}
and when I'm trying to combine them into that:
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation{
if ([[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options ]) {
return YES;
}
if ([RCTLinkingManager application:app
openURL:URL
options:options
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation ]) {
return YES;
}
return NO;
}
I'm getting the error: No known class method for selector 'application:openURL:options:sourceApplication:annotation'
Is it mean that sourceApplication and annotation are already included into options?
Any help welcome
you should call the FBSDKApplicationDelegate differently:
if ([[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]) {
return YES;
}
I need to add DeepLinking to my React Native app, and as mentioned in docs I need to add the method above #and.
// Add this above `#end`:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
I've added this method, but I also have similar one for Twitter login. Here's my AppDelegate.m:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
return [[Twitter sharedInstance] application:app openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
#end
I get an error:
Duplicate declaration of method 'application:openURL:options:'
How can it be solved? I'm not an iOS developer, so it's hard to figure out, but I think both two methods should be somehow combined.
As the error suggests, you can not have multiple functions with the same signature.
A simple solution here is merging your implementation into one, like this:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
return ([[Twitter sharedInstance] application:app openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]);
}
How do you combine these 2 functions?
If i run it like this, I get this on Xcode error: duplicate declaration of method 'application:openURL:options:'. The idea is to implement facebook and twitter login buttons.
// Twitter
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<NSString *,id> *)options {
return [[Twitter sharedInstance] application:app openURL:Url options:options];
}
// Facebook
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
// Add any custom logic here.
return handled;
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handledByFacebook = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
BOOL handledByTwitter = [[Twitter sharedInstance] application:application
openURL:url
options:options];
return handledByFacebook || handledByTwitter;
}
I am currently handling ios universal links through the RCTLinking API. For some reasons, I need to work with Firebase dynamic links and I am wondering if it is possible to use both in my app.
My issue is that the implementation in :
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
and
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
that seems incompatible as I would need to return both RCTLinkingManager and RNFirebaseLinks
Any solution?
A bit late to answering this question, but the currently proposed answer will not work. It will fail to open actions from Firebase In-App Messaging since the returned NO from RNFirebaseLinks will get overwritten by RCTLinkingManager with YES for the restoration handler.
If you come across this, try the following:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handledLink = [[RNFirebaseLinks instance] application:application openURL:url options:options];
if (!handledLink) {
handledLink = [RCTLinkingManager application:application openURL:url options:options];
}
return handledLink;
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *))restorationHandler {
BOOL handleRestore = [[RNFirebaseLinks instance] application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
if (!handleRestore) {
handleRestore = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}
return handleRestore;
}
My current set up and need for this is react-navigation v3 and react-native-firebase v5
You can have something like the code below inside your restorationHandler function:
BOOL handled = [[RNFirebaseLinks instance] application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
if (!handled) {
handled = [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
return handled;
The solution for me was:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if (url == nil) return false;
BOOL handled = [[RNFirebaseLinks instance]
application:application
openURL:url
options:options
] || [RCTLinkingManager
application:application
openURL:url
options:options
];
return handled;
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *))restorationHandler {
BOOL handled = [[RNFirebaseLinks instance]
application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler
] || [RCTLinkingManager
application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler
];
return handled;
}
react-native-firebase: 5.5.6, react-navigation 3.X
Not controlling the url to nil was resulting to a crash when starting the app.
To use FBSDK I need this snippet in app delegate
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation
];
// Add any custom logic here.
return handled;
}
To use LinkingManager I need this snippet in app delegate
#import "RCTLinkingManager.h"
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
They're obviously duplicates. How do I combine the two so both libraries work?
I don't know any Objective-C
Of course, you can implement this method only once in your AppDelegate.
[[FBSDKApplicationDelegate... and [RCTLinkingManager... both return a BOOL.
You can put both snippets in the same method. I would suggest to return YES, if both [RCTLinkingManager... and [[FBSDKApplicationDelegate... return YES. Otherwise, return NO.
It could look like this:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
BOOL handledFB = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation
];
BOOL handledRCT = [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
return handledFB || handledRCT;
}
I can't guarantee, that you can use FBSDKApplicationDelegate and RCTLinkingManager in the same app, because I have never worked with this. But your code should at least compile.
Wow, exactly what I was looking for! The accepted answer works great, except for a slight variation, since my FBSDK implementation is different (newer?). Because it uses:
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
I just tried to use the same parameters as FBSDK, and it works!
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
Full method:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handledFB = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
BOOL handledRCT = [RCTLinkingManager application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
return handledFB || handledRCT;
}
RN 0.59.x
For those who are using RNFirebase Linking:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handledFB = [[FBSDKApplicationDelegate sharedInstance]
application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
BOOL handledRCT = [RCTLinkingManager application:application openURL:url options:options];
if (!handledRCT) {
handledRCT = [[RNFirebaseLinks instance] application:application openURL:url options:options];
}
return handledFB || handledRCT;
}