在 iOS 9 中使用 Facebook 登录无法打开本机 Facebook 应用程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32566734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:38:19  来源:igfitidea点击:

Native Facebook app does not open with Facebook login in iOS 9

iosobjective-cfacebookios9facebook-login

提问by Bhumeshwer katre

I have updated iPhone 6 plus to iOS 9 beta and trying to perform Facebook login but each time its presenting UIWebView with Facebook login form.

我已将 iPhone 6 plus 更新为 iOS 9 beta 并尝试执行 Facebook 登录,但每次它都显示带有 Facebook 登录表单的 UIWebView。

I have Facebook sdk

我有 Facebook sdk

FB_IOS_SDK_VERSION_STRING @"3.24.0"
FB_IOS_SDK_TARGET_PLATFORM_VERSION @"v2.2"

And I am using following methods to perform Facebook Login

我使用以下方法来执行 Facebook 登录

    NSArray *permissions = @[@"email",@"user_birthday",@"public_profile"];


     FBSessionStateHandler completionHandler = ^(FBSession *session, FBSessionState status, NSError *error) {
         [self sessionStateChanged:session state:status error:error];
     };

     if ([FBSession activeSession].state == FBSessionStateCreatedTokenLoaded) {
     // we have a cached token, so open the session
         [[FBSession activeSession]openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
                                 fromViewController:nil
                                  completionHandler:completionHandler];
     } else {

     [self clearAllUserInfo];
    [[NSURLCache sharedURLCache] removeAllCachedResponses];

     // create a new facebook session
     FBSession *fbSession = [[FBSession alloc] initWithPermissions:permissions];
     [FBSession setActiveSession:fbSession];
     [fbSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
              fromViewController:nil
               completionHandler:completionHandler];
     }

I have following setting under plist file

我在 plist 文件下有以下设置

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>fbapi</string>
        <string>fbapi20130214</string>
        <string>fbapi20130410</string>
        <string>fbapi20130702</string>
        <string>fbapi20131010</string>
        <string>fbapi20131219</string>
        <string>fbapi20140410</string>
        <string>fbapi20140116</string>
        <string>fbapi20150313</string>
        <string>fbapi20150629</string>
        <string>fb-messenger-api20140430</string>
        <string>fbauth</string>
        <string>fbauth2</string>
   <array>

Please let me know what I am missing here. First it is checking for iPhone device Setting-> Facebook credentialsbut never open Facebook app for login. Seems it does not recognize Facebook app installed on device.

请让我知道我在这里缺少什么。首先它正在检查iPhone device Setting-> Facebook credentials但从不打开 Facebook 应用程序进行登录。似乎它无法识别设备上安装的 Facebook 应用程序。

回答by swiftBoy

Below is complete process for new "Facebook login".

以下是新的“Facebook 登录”的完整流程。



this is how I have revised my Facebook Login integration to get it work on latest update.

这就是我修改我的 Facebook 登录集成以使其适用于最新更新的方式。

Xcode 7.x, iOS 9, Facebook SDK 4.x

Xcode 7.xiOS 9Facebook SDK 4.x

Step-1. Download latest Facebook SDK (it includes major changes).

第1步。下载最新的 Facebook SDK(包括重大更改)。

Step-2. Add FBSDKCoreKit.frameworkand FBSDKLoginKit.frameworkto your project.

第2步。将FBSDKCoreKit.frameworkFBSDKLoginKit.framework添加到您的项目中。

Step-3. Now go to Project > Build Phases > add SafariServices.framework

第 3 步。现在转到 Project > Build Phases > add SafariServices.framework

Step-4. There are three changes in info.plistwe need to verify.

第四步。我们需要验证info.plist中的三个更改

4.1 Make sure you have below in your info.plist file

4.1 确保您的 info.plist 文件中有以下内容

<key>CFBundleURLTypes</key>
<array>
  <dict>
  <key>CFBundleURLSchemes</key>
  <array>
    <string><your fb id here eg. fbxxxxxx></string>
  </array>
  </dict>
</array>
  <key>FacebookAppID</key>
  <string><your FacebookAppID></string>
  <key>FacebookDisplayName</key>
<string><Your_App_Name_Here></string>
<key>CFBundleURLTypes</key>
<array>
  <dict>
  <key>CFBundleURLSchemes</key>
  <array>
    <string><your fb id here eg. fbxxxxxx></string>
  </array>
  </dict>
</array>
  <key>FacebookAppID</key>
  <string><your FacebookAppID></string>
  <key>FacebookDisplayName</key>
<string><Your_App_Name_Here></string>

4.2 Now add below for White-list Facebook Servers, this is must for iOS 9

4.2 现在为白名单 Facebook 服务器添加以下内容,这是 iOS 9 必须的

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>facebook.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
    <key>fbcdn.net</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
    <key>akamaihd.net</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
  </dict>
</dict>
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>facebook.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
    <key>fbcdn.net</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
    <key>akamaihd.net</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
  </dict>
</dict>

4.3 Add URL schemes

4.3 添加 URL 方案

<key>LSApplicationQueriesSchemes</key>
  <array>
      <string>fbapi</string>
      <string>fb-messenger-api</string>
      <string>fbauth2</string>
      <string>fbshareextension</string>
  </array>
<key>LSApplicationQueriesSchemes</key>
  <array>
      <string>fbapi</string>
      <string>fb-messenger-api</string>
      <string>fbauth2</string>
      <string>fbshareextension</string>
  </array>

Step-5. Now open AppDelegate.m file

第 5 步。现在打开AppDelegate.m 文件

5.1 Add below import statements, (remove old one).

5.1 添加下面的导入语句,(删除旧的)。

#import <FBSDKLoginKit/FBSDKLoginKit.h>
 #import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
 #import <FBSDKCoreKit/FBSDKCoreKit.h>

5.2 update following following methods

5.2 更新以下方法

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
  return [[FBSDKApplicationDelegate sharedInstance] application:application
                                                         openURL:url
                                               sourceApplication:sourceApplication
                                                      annotation:annotation];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
  [FBSDKAppEvents activateApp];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  return [[FBSDKApplicationDelegate sharedInstance] application:application
                                    didFinishLaunchingWithOptions:launchOptions];
}

Step-6. Now we need to modify our Login Controller, where we do Login task

第 6 步。现在我们需要修改我们的登录控制器,我们在那里做登录任务

6.1 Add these imports in Login ViewController.m

6.1 在 Login ViewController.m 中添加这些导入

#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>

6.2 Add Facebook Login Button

6.2 添加 Facebook 登录按钮

FBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init];
loginButton.center = self.view.center;
[self.view addSubview:loginButton];

6.3 Handle Login button click

6.3 处理登录按钮点击

-(IBAction)facebookLogin:(id)sender
{
    FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];

    if ([FBSDKAccessToken currentAccessToken])
    {
        NSLog(@"Token is available : %@",[[FBSDKAccessToken currentAccessToken]tokenString]);
        [self fetchUserInfo];
    }
    else
    {
        [login logInWithReadPermissions:@[@"email"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
         {
             if (error)
             {
                 NSLog(@"Login process error");
             }
             else if (result.isCancelled)
             {
                 NSLog(@"User cancelled login");
             }
             else
             {
                 NSLog(@"Login Success");

                 if ([result.grantedPermissions containsObject:@"email"])
                 {
                     NSLog(@"result is:%@",result);
                     [self fetchUserInfo];
                 }
                 else
                 {
                     [SVProgressHUD showErrorWithStatus:@"Facebook email permission error"];

                 }
             }
         }];
    }
}

6.4 Get user info (name, email etc.)

6.4 获取用户信息(姓名、电子邮件等)

-(void)fetchUserInfo
{
    if ([FBSDKAccessToken currentAccessToken])
    {
        NSLog(@"Token is available : %@",[[FBSDKAccessToken currentAccessToken]tokenString]);

        [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"id, name, email"}]
         startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
             if (!error)
             {
                 NSLog(@"results:%@",result);

                 NSString *email = [result objectForKey:@"email"];
                 NSString *userId = [result objectForKey:@"id"];

                 if (email.length >0 )
                 {
                     //Start you app Todo
                 }
                 else
                 {
                    NSLog(@“Facebook email is not verified");
                 }
             }
             else
             {
                 NSLog(@"Error %@",error);
            }
         }];
    }
}

Step-7. Now you can build project, you should get below screen.

第 7 步。现在您可以构建项目,您应该在屏幕下方。

enter image description here

在此处输入图片说明

Hope this will help you guys.

希望这会帮助你们。

References: Thanks to Facebook docs, Stackoverflow posts and Google.

参考资料:感谢 Facebook 文档、Stackoverflow 帖子和 Google。

回答by user3492452

This is by design. Facebook still have some issue with iOS9.

这是设计使然。Facebook 在 iOS9 上仍然存在一些问题。

See the Facebook team answere : https://developers.facebook.com/bugs/786729821439894/?search_idThanks

请参阅 Facebook 团队的回答:https: //developers.facebook.com/bugs/786729821439894/?search_id谢谢

回答by Mike.R

In the end I changed my Podfile to previous FB version:
From:

最后,我将 Podfile 更改为以前的 FB 版本:
来自:

pod 'FBSDKCoreKit' pod 'FBSDKLoginKit' pod 'FBSDKShareKit'
TO:

pod 'FBSDKCoreKit' pod 'FBSDKLoginKit' pod 'FBSDKShareKit'
到:

pod 'FBSDKCoreKit','~>4.5.1'
pod 'FBSDKLoginKit','~>4.5.1'
pod 'FBSDKShareKit','~>4.5.1'

From my point of view Facebook should check last login of the user and based on it trigger the correct Login flow.(and keep the small developers out of "web vs native war").

从我的角度来看,Facebook 应该检查用户的最后一次登录,并根据它触发正确的登录流程。(并使小开发人员远离“网络与原生War”)。

回答by Andrei Radulescu

Safari View Controller is by default in the Facebook SDK. For those of you who want to revert to the previous experience, see below. It works only for 3.x SDK, this will not work on 4.x.

Safari 视图控制器默认在 Facebook SDK 中。对于那些想要恢复到以前的体验的人,请参见下文。它仅适用于 3.x SDK,不适用于 4.x。

If you like to make the v3.x SDK (tested on v3.24.1) work like before (without opening Safari View Controller and make the app switch instead) call this code somewhere at the start of the app, e.g. didFinishLaunchingWithOptions:

如果您想让 v3.x SDK(在 v3.24.1 上测试)像以前一样工作(不打开 Safari 视图控制器并改为切换应用程序)在应用程序开头的某处调用此代码,例如 didFinishLaunchingWithOptions:

SEL useSafariSel = sel_getUid("useSafariViewControllerForDialogName:");
SEL useNativeSel = sel_getUid("useNativeDialogForDialogName:");
Class FBDialogConfigClass = NSClassFromString(@"FBDialogConfig");

Method useSafariMethod = class_getClassMethod(FBDialogConfigClass, useSafariSel);
Method useNativeMethod = class_getClassMethod(FBDialogConfigClass, useNativeSel);

IMP returnNO = imp_implementationWithBlock(^BOOL(id me, id dialogName) {
    return NO;
});
method_setImplementation(useSafariMethod, returnNO);

IMP returnYES = imp_implementationWithBlock(^BOOL(id me, id dialogName) {
    return YES;
});
method_setImplementation(useNativeMethod, returnYES);

It swizzles two methods from FBDialogConfig.

它混合了来自 FBDialogConfig 的两种方法。

Don't forget to import the objc/runtime.h header:

不要忘记导入 objc/runtime.h 头文件:

#import <objc/runtime.h>

@SimonCross some people just don't want to understand that Safari View Controller provides the best user experience - they think, or know for sure, that their users are not logged into Facebook in Safari, but are for sure logged in in the Facebook App.

@SimonCross 有些人只是不想明白 Safari 视图控制器提供了最好的用户体验——他们认为或肯定地知道,他们的用户没有在 Safari 中登录 Facebook,但肯定登录了 Facebook 应用程序.

回答by Chris Pan

@dan is right. In order to provide the best experience for users on iOS 9, the new SDK determines the best login flow automatically. If you're running on iOS 8 or earlier, the app switch will still be preferred.

@dan 是对的。为了在 iOS 9 上为用户提供最佳体验,新的 SDK 会自动确定最佳登录流程。如果您在 iOS 8 或更早版本上运行,应用程序开关仍将是首选。

回答by Chris Pan

After setting all the necessary .plist keys as mentioned in this column, I used following solution to come out of login problem.

在设置了本专栏中提到的所有必要的 .plist 键后,我使用以下解决方案解决了登录问题。

var fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.loginBehavior = FBSDKLoginBehavior.Web

So that it always logs in with in application.

这样它总是在应用程序中登录。

回答by Venu Gopal Tewari

With the release of iOS 9, Apple introduced some significant changes to app switching. This has affected iOS 9 apps integrated with Facebook. Most people will notice this in their experience using Facebook Login. In apps that use the newest SDK (v4.6 and v3.24), we will surface a flow using Safari View Controller (SVC) instead of fast-app-switching (FAS) because of additional dialog interstitials that add extra steps to the login process in FAS on iOS 9. Additionally, data that we've seen from more than 250 apps indicate that this is the best experience for people in the long run. Please read on for details. https://developers.facebook.com/blog/post/2015/10/29/Facebook-Login-iOS9

随着 iOS 9 的发布,Apple 对应用程序切换进行了一些重大更改。这影响了与 Facebook 集成的 iOS 9 应用程序。大多数人会在他们使用 Facebook 登录的体验中注意到这一点。在使用最新 SDK(v4.6 和 v3.24)的应用程序中,我们将使用 Safari 视图控制器 (SVC) 而不是快速应用程序切换 (FAS) 来显示流程,因为额外的对话框插页会向在 iOS 9 上的 FAS 中登录过程。此外,我们从 250 多个应用程序中看到的数据表明,从长远来看,这是人们的最佳体验。请继续阅读以了解详细信息。 https://developers.facebook.com/blog/post/2015/10/29/Facebook-Login-iOS9

回答by Haroun SMIDA

Facebook has changed Facebook login behavior for iOS9.

Facebook 已经更改了 iOS9 的 Facebook 登录行为。

Here is the quote from Facebook blog post:

这是Facebook 博客文章中的引述:

We've been monitoring data and CTRs for over 250 apps over the last 6 weeks since iOS 9 launched. The click-through rate (CTR) of SVC Login outperforms the CTR of app-switch Login and is improving at 3x the rate of the app-switch experience. This indicates that the SVC experience is better for people and developers today, and will likely be the best solution in the long run. For this reason, the latest Facebook SDK for iOS uses SVC as the default experience for Login.

自 iOS 9 发布以来的过去 6 周内,我们一直在监控超过 250 个应用程序的数据和点击率。SVC 登录的点击率 (CTR) 优于应用切换登录的点击率,并且正在以应用切换体验速度的 3 倍提高。这表明 SVC 体验对当今的人们和开发人员来说更好,并且从长远来看可能是最好的解决方案。为此,适用于 iOS 的最新 Facebook SDK 使用 SVC 作为登录的默认体验。

回答by vien vu

I know it is old. But you can put this code to your application:(UIApplication *)application didFinishLaunchingWithOptions:

我知道它很旧了。但是你可以把这个代码放到你的application:(UIApplication *)application didFinishLaunchingWithOptions:

SEL useNativeSel = sel_getUid("useNativeDialogForDialogName:");
Class FBSDKServerConfiguration = NSClassFromString(@"FBSDKServerConfiguration");


Method useNativeMethod = class_getInstanceMethod(FBSDKServerConfiguration, useNativeSel);

IMP returnYES = imp_implementationWithBlock(^BOOL(id me, id dialogName) {
    return YES;
});
method_setImplementation(useNativeMethod, returnYES);

And FacebookSDKwill login through native app when app installed instead of browser.

FacebookSDK安装应用程序而不是浏览器时,将通过本机应用程序登录。

回答by Sushil Sharma

This worked for me. Add this to your .plist.

这对我有用。将此添加到您的.plist.

<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>fb</string>
    </array>

For iOS9, we need to add key to our .plistfor URL Schemes.

对于 iOS9,我们需要为我们.plist的 URL Schemes添加密钥。