简体   繁体   English

在iOS 9中,本地Facebook应用程序无法通过Facebook登录打开

[英]Native Facebook app does not open with Facebook login in iOS 9

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测试版,并试图执行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 credentials but never open Facebook app for login. 首先,它正在检查iPhone device Setting-> Facebook credentials但从未打开Facebook应用程序进行登录。 Seems it does not recognize Facebook app installed on device. 似乎它无法识别设备上安装的Facebook应用程序。

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. 步骤1。 Download latest Facebook SDK (it includes major changes). 下载最新的Facebook SDK(包括重大更改)。

Step-2. 第2步。 Add FBSDKCoreKit.framework and FBSDKLoginKit.framework to your project. FBSDKCoreKit.frameworkFBSDKLoginKit.framework添加到您的项目中。

Step-3. 步骤3。 Now go to Project > Build Phases > add SafariServices.framework 现在转到Project> Build Phases>添加SafariServices.framework

Step-4. 第4步。 There are three changes in info.plist we 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> 

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> 

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> 

Step-5. 步骤-5。 Now open AppDelegate.m file 现在打开AppDelegate.m文件

5.1 Add below import statements, (remove old one). 5.1添加以下import语句,(删除旧语句)。

 #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. 步骤-6。 Now we need to modify our Login Controller, where we do Login task 现在我们需要修改Login Controller,我们在那里执行Login任务

6.1 Add these imports in Login ViewController.m 6.1在Login ViewController.m中添加这些导入

 #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. 步骤-7。 Now you can build project, you should get below screen. 现在你可以建立项目,你应该到屏幕下方。

在此输入图像描述

Hope this will help you guys. 希望这会帮助你们。

References : Thanks to Facebook docs, Stackoverflow posts and Google. 参考文献 :感谢Facebook文档,Stackoverflow帖子和谷歌。

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_id Thanks 请参阅Facebook团队回复: https//developers.facebook.com/bugs/786729821439894/? search_id谢谢

In the end I changed my Podfile to previous FB version: 最后我将我的Podfile更改为以前的FB版本:
From: 从:

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

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应该检查用户的最后一次登录,并根据它触发正确的登录流程。(并让小型开发人员远离“web vs native war”)。

@dan is right. @dan是对的。 In order to provide the best experience for users on iOS 9, the new SDK determines the best login flow automatically. 为了在iOS 9上为用户提供最佳体验,新SDK会自动确定最佳登录流程。 If you're running on iOS 8 or earlier, the app switch will still be preferred. 如果您在iOS 8或更早版本上运行,则仍会首选应用程序切换。

Safari View Controller is by default in the Facebook SDK. 默认情况下,Safari视图控制器位于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. 它仅适用于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, eg didFinishLaunchingWithOptions: 如果您想使v3.x SDK(在v3.24.1上测试)像以前一样工作(不打开Safari View Controller并改为使用应用程序切换),请在应用程序启动时的某处调用此代码,例如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 View Controller提供了最佳的用户体验 - 他们认为或肯定地知道他们的用户没有登录Safari中的Facebook,但确实登录了Facebook App 。

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. 因此它始终在应用程序中登录。

With the release of iOS 9, Apple introduced some significant changes to app switching. 随着iOS 9的发布,Apple对应用切换进行了一些重大改变。 This has affected iOS 9 apps integrated with Facebook. 这影响了与Facebook集成的iOS 9应用程序。 Most people will notice this in their experience using Facebook Login. 大多数人会在使用Facebook登录的经验中注意到这一点。 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. 在使用最新SDK(v4.6和v3.24)的应用程序中,我们将使用Safari视图控制器(SVC)而不是快速应用程序切换(FAS)来显示流程,因为其他对话框插页式广告会为其添加额外的步骤在iOS 9上的FAS中登录过程。此外,我们从超过250个应用程序中看到的数据表明,从长远来看,这对于人们来说是最好的体验。 Please read on for details. 请继续阅读以了解详情。 https://developers.facebook.com/blog/post/2015/10/29/Facebook-Login-iOS9 https://developers.facebook.com/blog/post/2015/10/29/Facebook-Login-iOS9

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. 自iOS 9推出以来,我们一直在监控超过250个应用的数据和点击率。 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. SVC登录的点击率(CTR)优于app-switch登录的点击率,并且以app-switch体验的3倍速度提升。 This indicates that the SVC experience is better for people and developers today, and will likely be the best solution in the long run. 这表明SVC体验对于今天的人和开发人员来说更好,并且从长远来看可能是最好的解决方案。 For this reason, the latest Facebook SDK for iOS uses SVC as the default experience for Login. 因此,最新的iOS SDK SDK使用SVC作为Login的默认体验。

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 .plist for URL Schemes. 对于iOS9,我们需要为URL Schemes添加.plist密钥。

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 FacebookSDK will login through native app when app installed instead of browser. 当安装应用程序而不是浏览器时, FacebookSDK将通过本机应用程序登录。

Putting this one in appdelegate solved my problem 把这个放在appdelegate解决了我的问题

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
    }

Adding below lines to .plist file helped me: .plist添加到.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>fbauth</string>
      <string>fbauth2</string>
      <string>fb-messenger-api20140430</string>
    </array>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM