【问题标题】:Handling openURL: with Facebook and Google处理 openURL:使用 Facebook 和 Google
【发布时间】:2018-10-26 03:17:33
【问题描述】:

我的应用中的用户可以使用 2 个服务登录:Facebook 或 Google

一切正常,但是,在:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation: (id)annotation {
    ...
}

我应该决定是调用 Facebook 回调还是 Google 回调

如果用户有应用程序,这很容易,比我由 sourceApplication 决定 但如果不是(没有链接本地 Facebook 帐户、没有 FB 应用程序、没有 GooglePlus 应用程序),它会链接到浏览器 :( 我不知道它是来自 Facebook 还是来自 Google

有没有办法决定调用什么?喜欢

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation: (id)annotation {

    // how to decide?
    if (facebook) {

        return [FBSession.activeSession handleOpenURL:url];

    } else if (google) {

        return [GPPURLHandler handleURL:url sourceApplication:sourceApplication annotation:annotation];

    }

}

【问题讨论】:

    标签: ios facebook cocoa-touch oauth-2.0


    【解决方案1】:

    我们不需要显式检查 URL,下面的代码可以做到:

    - (BOOL)application: (UIApplication *)application openURL: (NSURL *)url sourceApplication: (NSString *)sourceApplication annotation: (id)annotation
    {
    
        if ([GPPURLHandler handleURL:url sourceApplication:sourceApplication annotation:annotation]) {
            return YES;
        }else if([FBAppCall handleOpenURL:url sourceApplication:sourceApplication]){
            return YES;
        }
    
        return NO;
    }
    

    【讨论】:

      【解决方案2】:

      这可能是最简单的解决方案,

      import GoogleSignIn
      import FBSDKCoreKit
      
          func application(_ application: UIApplication,
                       open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
          if GIDSignIn.sharedInstance().handle(url) {
              return true
          } else if ApplicationDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation) {
              return true
          }
          
          return false
      }
      
      @available(iOS 9.0, *)
      func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
          if GIDSignIn.sharedInstance().handle(url) {
              return true
          } else if ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation]
              ) {
              return true
          }
          return false
      }
      

      【讨论】:

        【解决方案3】:

        已接受答案的 iOS 9.0 及更高版本的 Swift 版本可能是这样的:

        import FacebookCore
        
        [...]
        
            func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
                if (GIDSignIn.sharedInstance().handle(url)) {
                    return true
                } else if (ApplicationDelegate.shared.application(app, open: url, options: options)) {
                    return true
                }
        
                return false
            }
        

        尝试使用每个 SDK 处理 URL,第一个识别它的 SDK 结束执行返回 true。如果没有 SDK 可以处理 URL,则返回 false。

        希望对大家有所帮助

        哈维

        【讨论】:

          【解决方案4】:

          您可以让 Google SDK 或 Facebook SDK 尝试处理,如果 SDK 无法处理,则允许其他 SDK 尝试:

              @available(iOS 9.0, *)
          private func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any])
              -> Bool {
                  let handled: Bool = SDKApplicationDelegate.shared.application(application, open: url, options: options)
          
                  if handled { return handled }
          
                  return GIDSignIn.sharedInstance().handle(url,
                                                           sourceApplication:options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
                                                           annotation: [:])
          }
          
          //deprecated method iOS 8 and older
          func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
              let handled: Bool =  SDKApplicationDelegate.shared.application(application,
                                                                             open: url,
                                                                             sourceApplication: sourceApplication,
                                                                             annotation: annotation)
          
              if handled { return handled }
          
              return GIDSignIn.sharedInstance().handle(url,
                                                       sourceApplication: sourceApplication,
                                                       annotation: annotation)
          }
          

          【讨论】:

            【解决方案5】:

            你可以试试这个 Swift 4.2 版本:

            func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool 
            {
                if (url.scheme?.hasPrefix("fb"))! {
                    return SDKApplicationDelegate.shared.application(app, open: url, options: options)
                } 
                else
                {
                    return GIDSignIn.sharedInstance().handle(url as URL?, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
                                                                             annotation: options[UIApplicationOpenURLOptionsKey.annotation])
                }           
            }
            

            【讨论】:

            • 虽然它给出了答案的解决方案。解释一下代码就好了
            • 那是我相信错误的代码,因为谷歌和 Facebook 在所有情况下都会处理 url...它应该是有条件的,就像在接受的答案中一样
            • 为 facebook URL 添加前缀检查
            【解决方案6】:

            iOS9 已弃用方法“application:openURL:sourceApplication:annotation:”。所以现在你可以使用like了。

            - (BOOL)application:(UIApplication *)app
                    openURL:(NSURL *)url
                    options:(NSDictionary *)options {
                   // For Google sign in SDK
                   if ([[GIDSignIn sharedInstance] handleURL:url
                                           sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
                                                  annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]) {
                      return YES;
                   // For Facebook SDK
                   }else if ( [[FBSDKApplicationDelegate sharedInstance] application:app
                                                                      openURL:url
                                                            sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
                                                                   annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]){
                      return YES;
                  //For Google plus SDK
                  }else if ([GPPURLHandler handleURL:url
                                   sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
                                          annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]){
                      return YES;
                  }
            
                 return NO;
            }
            

            【讨论】:

              【解决方案7】:

              对于 Swift 用户,(来自 user2144179 的想法)

              导入以下框架

              import Firebase
              import GoogleSignIn
              import FacebookCore // (FBSDKCore's alternative for swift)
              

              在你的委托方法中

              // when your target is under iOS 9.0
              func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
                  let isFBOpenUrl = SDKApplicationDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
                  let isGoogleOpenUrl = GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation)
                  if isFBOpenUrl { return true }
                  if isGoogleOpenUrl { return true }
                  return false
              }
              

              如果您的目标是 9.0+,您也可以使用另一个“打开网址:”方法。 SDK 也包含一个方法。

              Firebase 参考:https://firebase.google.com/docs/auth/ios/google-signin

              Facebook 参考:https://developers.facebook.com/docs/swift/reference/classes/applicationdelegate.html

              【讨论】:

                【解决方案8】:
                - (BOOL)application:(UIApplication *)application
                            openURL:(NSURL *)url
                   sourceApplication:(NSString *)sourceApplication
                         annotation:(id)annotation
                {
                
                
                   if( [GPPURLHandler handleURL:url
                                  sourceApplication:sourceApplication
                                     annotation:annotation])
                   {
                       return [GPPURLHandler handleURL:url
                                     sourceApplication:sourceApplication
                                            annotation:annotation];
                   }
                    else if([[FBSDKApplicationDelegate sharedInstance] application:application
                                                                          openURL:url
                                                                sourceApplication:sourceApplication
                                                                       annotation:annotation])
                    {
                        return [[FBSDKApplicationDelegate sharedInstance] application:application
                                                                              openURL:url
                                                                    sourceApplication:sourceApplication
                                                                           annotation:annotation];
                    }
                    return NO;
                }
                

                【讨论】:

                  【解决方案9】:

                  您可以尝试以下方法:

                  if ([[url absoluteString] rangeOfString:@"<Your Google Bundle ID>"].location ==            NSNotFound)
                  {
                      // Call FBAppCall's handleOpenURL:sourceApplication to handle Facebook app responses
                      BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
                      // You can add your app-specific url handling code here if needed
                      return wasHandled;
                  }
                  else
                  {
                      return [GPPURLHandler handleURL:url
                                    sourceApplication:sourceApplication
                                           annotation:annotation];
                  }
                  return YES;
                  

                  中调用上述方法
                  (BOOL)application:(UIApplication *)application
                            openURL:(NSURL *)url
                  sourceApplication:(NSString *)sourceApplication
                         annotation:(id)annotation 
                  

                  在你的appDelegeate.m

                  基本上这要做的是检查 url 前缀,然后如果 url 前缀是 ur google+ bundle id 则调用 google+ 方法,如果不是,它将调用 fb 方法。 希望这会有所帮助

                  【讨论】:

                  • 您可以交替测试 URL 的方案是否以“fb”开头,这将使代码应用 ID 独立。
                  • 天才,我这辈子都想不通为什么只有 FB 或 G+ 有效,而不能同时工作
                  【解决方案10】:

                  【讨论】:

                  • canOpenURL 首先,可以让您知道设备上安装了哪些应用程序。您可以检查 URL 的前缀以确定它来自哪个服务。 Facebook 应用的 URL 将以 fb: 开头
                  • @Idles 记住这是回调方法。如果您的应用同时支持 facebook 和 google url,canOpenUrl 总是为两者返回 YES。你是对的,你可以检查 url,但通常一个库有一个 handleURL: 方法,它为你返回一个布尔值。除非您想自己施展魔法,否则您不必费心。
                  猜你喜欢
                  • 2012-02-18
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-11-10
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多