Facebook iOS SDK 3.14の変更点で注意すべきところ


[Facebook SDK for iOS](https://developers.facebook.com/docs/ios)といえば、アップデートのたびに、大幅な仕様変更が入り、Facebookのdeveloperドキュメントとの乖離が起きる（特に日本語ドキュメントは常に古い・・・）ことで有名ですが、3.14の修正でハマったところを残しておきます。

2014/7/8現在、最新版は3.15.1です。

## iOS NativeのFacebook設定によるログインがデフォルトではなくなった

まずiOS6以降の機能であるネイティブのFacebook設定によるログイン、パーミッション設定がデフォルトの動作ではなくなったようです。下記のリンク先のようなアプリの遷移をせずに認証できる機能のことです。

https://developers.facebook.com/docs/facebook-login/ios/v2.0#dialogs-iosnative

アップグレードガイドによると、新しいFacebookのログイン方式は、iOSのnativeの方式では適用出来ないので、デフォルトの動作を変えたということなんでしょうね。

>Upgrading from 3.13 to 3.14
...
The New Facebook Login does not apply to iOS device account authentication.
The default login behavior has changed from FBSessionLoginBehaviorUseSystemAccountIfPresent to FBSessionLoginBehaviorWithFallbackToWebView.
https://developers.facebook.com/docs/ios/upgrading

## iOSのネイティブによるログインを実現するにはどうするか

それでも、Facebook AppやSafariなどにアプリ遷移するよりネイティブによるログインをSDKで実現したい場合どうするか。

1. Facebook SDKを3.13にダウングレードして使う
2. Facebook SDKのソースを少し変更してしまう（cocoapods経由なら可能）
3. セッション取得部分のコードを変更する

1番は簡単な方法ですが、今後アップデートしたくても、できないリスクがあります。
2番はFBSession.mのメソッドを少し変更すると可能です。

```
+ (BOOL)openActiveSessionWithReadPermissions:(NSArray *)readPermissions
                                allowLoginUI:(BOOL)allowLoginUI
                           completionHandler:(FBSessionStateHandler)handler {
    return [FBSession openActiveSessionWithPermissions:readPermissions
                                          allowLoginUI:allowLoginUI
                                    allowSystemAccount:NO //←YESにしてしまう
                                                isRead:YES
                                       defaultAudience:FBSessionDefaultAudienceNone
                                     completionHandler:handler];
}
```

あまり動作確認してないですが、これでもいけました。ただこの方法も避けたい・・・

3番はセッションを開くメソッドに少し分岐をつけて対応する方法。

このようなコードを

```
[FBSession openActiveSessionWithReadPermissions:@[@"email"]
                                       allowLoginUI:YES
                                  completionHandler:
                                          ^(FBSession *session, FBSessionState state, NSError *error) {
                                          }
];
```

下記のように変更します

```
	FBSessionStateHandler completionHandler = ^(FBSession *session, 	FBSessionState status, NSError *error) {};

    if ([FBSession activeSession].state == FBSessionStateCreatedTokenLoaded) {
        [[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
                  completionHandler:completionHandler];
    } else {
		//セッション削除
	  [FBSession.activeSession closeAndClearTokenInformation];
	  [FBSession renewSystemCredentials:^(ACAccountCredentialRenewResult result, NSError *error) {}];
     [FBSession setActiveSession:nil];

        FBSession *fbSession = [[FBSession alloc] initWithPermissions:@[@"email"]];
        [FBSession setActiveSession:fbSession];
        [fbSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
                  completionHandler:completionHandler];
    }
```

これでいけました。

参考
>Native Facebook Login stopped working after SDK update to 3.14
http://stackoverflow.com/questions/23476499/native-facebook-login-stopped-working-after-sdk-update-to-3-14