Social.frameworkを使用してFacebook投稿するときのFacebookアプリによる仕様変更まとめ

アプリからのSNS投稿を簡単に実装できるiOSのSocial.frameworkですが、
Facebook iOS公式アプリ（ver29.0以降, 2015/04/24リリース）がインストールされている場合に、
これまでと異なる挙動をするため、変更点についてまとめました。
(2015/6/23時点)

![setInitialText.png](https://qiita-image-store.s3.amazonaws.com/0/34488/14d6aa53-c72f-9200-739e-00002d2e3651.png)

#投稿画面に初期設定文が自動挿入されない
投稿画面に文字を自動挿入しておくSLComposeViewController -setInitialTextが条件によって無効になります。

これまで：
投稿画面を表示したときにデフォルトで文字を自動挿入することが可能でした

現状：
Facebookアプリがインストールされている状態では自動挿入されるはずの文字が挿入されません。


```objc

SLComposeViewController *vc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    [vc setInitialText:@"最新のFacebook iOSアプリがインストールされているとき、表示されません。"];
    [self presentViewController:vc animated:YES completion:nil];

```

```swift:Swift

let vc = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
vc.setInitialText("最新のFacebook iOSアプリがインストールされているとき、表示されません。")
presentViewController(vc, animated: true, completion: nil)

```

#Facebook投稿可能かの判定方法
![FacebookAccount.png](https://qiita-image-store.s3.amazonaws.com/0/34488/88b4d917-0bbb-9cd6-7abe-7d5b7515254a.png)

これまで：
-isAvailableForServiceTypeを使用すると、iOS端末にFacebookアカウントが登録されているかを判定できました。

現状：
以下の条件に分かれます。
・Facebook iOSアプリがインストールされている場合、YESを返す。
・Facebook iOSアプリがインストールされておらず、iOS端末へのFacebookアカウント登録が無い場合、NOを返す。


```objc:Objective-C

BOOL isAvailableFacebook = [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook];

```

```swift:Swift

let isAvailableFacebook = SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook)

```

#Facebookアカウントが無い場合の設定画面へのリンク付きダイアログの表示方法
![GoSettingDialog.png](https://qiita-image-store.s3.amazonaws.com/0/34488/184e9d53-731e-c10b-7623-13a979f72fe4.png)

これまで：
iOS端末にFacebookアカウントが登録されていない状態でSLComposeViewControllerを表示すると設定画面へのリンク付きのダイアログが表示されていました。

現状：
iOS端末にFacebookアカウントが登録されていない、かつ、Facebookアプリがインストールされていない状態のときのみ表示されます。

```objc
SLComposeViewController *vc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[self presentViewController:vc animated:YES completion:nil];

```

```swift:Swift

let vc = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
presentViewController(vc, animated: true, completion: nil)

```

#iOS端末にFacebookアカウントが登録されていないときの投稿ボタン押下時
これまで：
iOS端末にFacebookアカウントが登録されていない状態では、
設定画面へのリンク付きのダイアログが表示されていました。

現状：
Facebookアプリがインストールしている場合、条件によって挙動が異なります。
・Facebookアプリでログインしているとき、Facebookアプリでログインしているユーザから投稿されます。
・Facebookアプリでログインしていないとき、ログインを求めるダイアログが表示される。
（iOS端末にFacebookアカウントが登録されている状態であっても）
![NoLoginDialog.png](https://qiita-image-store.s3.amazonaws.com/0/34488/7cc7aaae-4099-7200-5f59-6df8092ea211.png)


#投稿画面を閉じたときの閉じ方の判定方法
これまで：
「投稿」「キャンセル」のどちらのボタンを押して投稿画面を閉じたかを判定できました。

現状：
区別ができなくなっています。


```objc:Objective-C
SLComposeViewController *vc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[vc setCompletionHandler:^(SLComposeViewControllerResult result) {
         if (result == SLComposeViewControllerResultDone) {
             NSLog(@"Done"); //キャンセルしてもDoneと判定されてしまう
         } else if (result == SLComposeViewControllerResultCancelled) {
             NSLog(@"Cancel");
         }
    }];

```

```swift:Swift
let vc = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
vc.completionHandler = {(result:SLComposeViewControllerResult) -> Void in
    switch result {
        case SLComposeViewControllerResult.Done:
            print("Done") //キャンセルしてもDoneと判定されてしまう
        case SLComposeViewControllerResult.Cancelled:
            print("Cancel")
    }
}

```




#Facebook SDKを使用してiOS端末に登録されているアカウントから認証を得るとき
Facebook SDKを使用してiOS端末から認証トークンを取得する際に使用しているメソッドにも影響があり、
iOS端末にアカウントが登録されていない場合にFacebookアプリにURLスキームします。
URLスキームした後に認証を行い、UIApplicationのURLスキームのdelegateの中でURLの中に認証情報が含まれます。

```objc:Objective-C
[[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
                          completionHandler:nil];

```

#Facebook公式の見解
Facebook Developerページで開発者からのsetInitialTextの挙動変更について以下のように回答しています。
https://developers.facebook.com/bugs/962985360399542/
「SLComposeViewControllerはAppleのframeworkなので、Appleに問い合わせてください。
加えて、Facebook Platform Policyは投稿画面での自動挿入文を許可していません。
ユーザに最善の体験をさせてあげたいのであれば、Facebook SDKを使用することをオススメします。」

#参考
http://qiita.com/kenmaz/items/6faf1b4a701e9b40fb58
https://developers.facebook.com/bugs/962985360399542/

#まとめ
最新のFacebook iOSアプリがインストールされている状態でのSocial.frameworkの挙動変更についてまとめました。
全体的にFacebookアプリが存在するときに従来にはなかったFacebookアプリでの認証・投稿の挙動が追加されています。
Facebook SDKのアップデート内容から分かるようにFacebookは認証・投稿をFacebookアプリで実行するように変更していっているようです。