处理 openURL:使用 Facebook 和 Google

Posted

技术标签:

【中文标题】处理 openURL:使用 Facebook 和 Google【英文标题】:Handling openURL: with Facebook and Google 【发布时间】:2013-06-16 09:26:19 【问题描述】:

我的应用程序中的用户可以使用 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];

    


【问题讨论】:

【参考方案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】:

对于 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

【讨论】:

【参考方案3】:

您可以尝试以下方法:

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+ 有效,而不能同时工作【参考方案4】:

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;

【讨论】:

【参考方案5】:

已接受答案的 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。

希望对大家有所帮助

哈维

【讨论】:

【参考方案6】:

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

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

【讨论】:

【参考方案7】:

你可以试试这个 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 添加前缀检查【参考方案8】:

您可以让 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)

【讨论】:

【参考方案9】:

你会想要使用[[UIApplication sharedApplication] canOpenURL:]

【讨论】:

canOpenURL 首先,可以让您知道设备上安装了哪些应用程序。您可以检查 URL 的前缀以确定它来自哪个服务。 Facebook 应用的 URL 将以 fb: 开头 @Idles 记住这是回调方法。如果您的应用同时支持 facebook 和 google url,canOpenUrl 总是为两者返回 YES。你是对的,你可以检查 url,但通常一个库有一个 handleURL: 方法,它为你返回一个布尔值。除非您想自己施展魔法,否则您不必费心。【参考方案10】:
- (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;

【讨论】:

以上是关于处理 openURL:使用 Facebook 和 Google的主要内容,如果未能解决你的问题,请参考以下文章

Facebook 和 Google+ 登录

iOS AppDelegate.m:处理 openUrl RCTLinkingManager 和 Twitter - 方法 'application:openURL:options:' 的重复声明

如何从我在 iOS 中制作的应用程序中打开新应用程序 (Facebook)

APPDelegate 中的 openURL 转换错误 NSString -> String (Swift & iOS8)

处理应用程序:openURL:sourceApplication: 在 iOS 应用程序中打开文件

处理OpenURL 方法。显示 modalviewcontroller 并传递 url 信息