如何修复方法的重复声明与破坏代码

时间:2016-02-21 14:14:10

标签: objective-c

我正在尝试将Google signin SDK包含到我的AppDelegate.m文件中,但它会抛出此错误。

就像我只能定义方法的一个实例。

// 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

2 个答案:

答案 0 :(得分:6)

我想答案可能很简单:

- (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];
}

如果添加更多内容,请在任何代理处理openURL时返回YES。订单无关紧要。此方法也已弃用(请改用-application:openURL:options:),因此如果您希望应用在未来的更改中继续使用,则需要避免使用-application:openURL:sourceApplication:annotation:

UPD:如果您现在想要使用我的解决方案"还有高斯布鲁因解决方案中的优点,那么如果你想要长远的东西 - 得到一些东西从它肯定。

答案 1 :(得分:1)

@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

毕竟

您可以将所有AppDelegate方法委派给外部类。

您的麻烦是广泛使用appDelegate方法&#39;。

似乎没有人想在应用中清理应用代理,因为&#39;它只是工作&#39;。我只是告诉你(不好或不好?不知道)责任链模式和简单授权的例子。

请记住,您可以将大多数AppDelegate方法委托给其他对象/类,例如,您可以提供智能&#39; PushNotificationsRouter&#39;这将处理所有推送通知相关的方法。