Reputation: 131
I am trying to include Google signin SDK to my AppDelegate.m file and it throw this error.
Its like I can only define one instance of the method.
// Facebook SDK
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [RNGoogleSignin application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}
@end
Upvotes: 3
Views: 2583
Reputation: 6032
I guess the answer could be quite simple:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
if([[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation])
{
return YES;
}
return [RNGoogleSignin application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
If you add more, return YES
when any of the agents handles the openURL. Order is irrelevant. Also this method is deprecated (use -application:openURL:options:
instead), so you need to avoid using -application:openURL:sourceApplication:annotation:
if you want your app to survive future changes.
UPD: Use my solution if you "want it now", there's good points in gaussblurinc's solution as well, so if you want something for a long run - derive something from it for sure.
Upvotes: 9
Reputation: 3692
@interface Services : NSObject<UIApplicationDelegate> // or ApplicationDelegateServices?
@property (strong, nonatomic, readonly) NSArray <id<UIApplicationDelegate>> *services;
@end
@interface Services()
@property (strong, nonatomic, readwrite) NSArray <id<UIApplicationDelegate>> *services;
@end
@class RNGoogleSignin;
@class FBSDKApplicationDelegate;
@implementation Services
- (void)setup {
// put all items inside here
//
id<UIApplicationDelegate> googleApplicationDelegate = (<UIApplicationDelegate>)[RNGoogleSignin class];
id<UIApplicationDelegate> facebookApplicationDelegate = (<UIApplicationDelegate>)[FBSDKApplicationDelegate sharedInstance];
self.services = @[facebookApplicationDelegate, googleApplicationDelegate];
}
// services - create chain of responsibility for openURL scheme
// they only need to adopt to protocol canOpenURL and openURL
// each service is <UIApplicationDelegate>
- (NSArray <id<UIApplicationDelegate>>*) chainForSelector:(SEL)selector {
return [self.services filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id<UIApplicationDelegate> _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return [evaluatedObject respondsToSelector:selector];
}]];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// find all that responds to selector
// filteredArrayUsingPredicate
NSArray *chain = [self chainForSelector:_cmd];
// or put your custom logic here, because all items in delegate are good enough to perform selector
for (id<UIApplicationDelegate> delegate in chain) {
if([delegate application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation]) {
return YES;
}
}
return NO;
}
@end
@interface AppDelegate<UIApplicationDelegate>
@property (nonatomic, weak) id<UIApplicationDelegate> services;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// check that services responds to delegate method
// if ([services respondsToSelector:...])
if ([self.services respondsToSelector:_cmd]) {
return [self.services application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation];
}
return NO/YES; // your choice
}
@end
After all
You can delegate all AppDelegate methods to external classes.
Your trouble was 'extensive usage of appDelegate methods'.
It seems that nobody wants to cleanup app delegate in apps because 'it just works'. I just show you ( bad or good? don't know ) an example of chain of responsibility pattern and simple delegation.
Remember, you can delegate most of your AppDelegate methods to other objects/classes, for example, you can provide smart 'PushNotificationsRouter' that will handle all push notification-related methods.
Upvotes: 1