iOS9でFacebook Single Sign On

今更ながらiOSアプリでのFacebookログインを実装しようとしてみたら、
iOS9でセキュリティが強化された関係で公式チュートリアルのままでは動かなかったので対処法をメモ。

ついでに、SwiftでCocoaPodsを使ってSDKを導入する方法もメモ。

追記

[公式ドキュメント](https://developers.facebook.com/docs/ios/ios9)に全部書いてあったッ！！！

## 追記(2015/10/02) NativeのFacebookアプリが立ち上がることはなくなった？

https://developers.facebook.com/bugs/786729821439894/?search_id

FBSDK 4.6から仕様が変わったようです。

iOS9以降、別アプリを立ち上げようとすると「〜を開こうとしています」というダイアログが表示されることを嫌って、Nativeの認証をやめ、SafariViewを使って認証するようにした、と回答されています（そして回答以降のコメントはこの変更についての不評の嵐・・・

# TL;DR

iOS9 からは Info.plistにLSApplicationQueriesSchemesの設定も追加しないと、
常にSafariでのFacebookログインになっちゃうよ

# pod 'FBSDKLoginKit', '4.4.0'

Podfileを書いて`pod install`

※バージョンは [CocoaPods.org](https://cocoapods.org/?q=fbsdk)とかで確認して適宜最新版に

```rb
platform :ios, '8.0'
use_frameworks!

target 'FacebookLoginSample' do
  pod 'FBSDKLoginKit', '4.4.0'
end
```

このとき`use_frameworks!`を書き忘れないように注意

- FBSDKLoginKit
- FBSDKCoreKit
- Bolts

が依存で入ってくる

Podsの準備ができたので、〜.xcodeproj で開いていたプロジェクトは閉じて、〜.xcworkspace の方をXcodeで開き直す

# Bridging-Header.hを作成・・・は、しない

Facebook SDKはObjCなので、Swiftから呼び出すにはBridging Headerが必要

と、ドキュメントには書いてあるけど、`use_frameworks!`をつけてpod installしていると実は不要。というか、それだとむしろビルドできない

そのまま

```swift
import FBSDKLoginKit
```

でインポートできる

# Info.plist に設定追加

公式チュートリアル通り、TARGET設定のInfoのタブを開いて

Custom iOS Target Propertiesに

- FacebookAppID
- FacebookDisplayName

を追加

別欄のURL Typesに

- URL Scheme: fb*******

を追加。他はそのまま空欄でOK

Facebookのチュートリアルだと、Custom iOS Target Propertiesに自分でURL Typesのレコードを追加するようなスクリーンショットになってるので注意

`'InvalidOperationException', reason: 'fb********** is not registered as a URL scheme. Please add it in your Info.plist'`

とか表示されたらこのあたりの設定ミスを疑う

自分の場合は、URL TypesをCustom iOS Target Propertiesに書いていてしばらく悩んだ

で、それを解決して動いたとおもったら、Safariが開いてFacebookログインを求められる


# LSApplicationQueriesSchemesでfbauthを許可

本題のiOS9での注意点。

Info.plistに

```
LSApplicationQueriesSchemes (Array)
  item0 : (String) fbauth
```

を設定してやらないと、fbauthのカスタムスキーマを開くことができず、
FacebookアプリではなくSafariでの認証になってしまう

```
-canOpenURL: failed for URL: "fbauth://authorize/?client_id=（略）" - error: "This app is not allowed to query for scheme fbauth"
```

とかがログに出てたらこれが原因のはず

参考
[parse.com - swift 2 parse facebookSDK ios9 - Stack Overflow](http://stackoverflow.com/questions/30736663/swift-2-parse-facebooksdk-ios9)

これで無事Facebookアプリでのログインができるようになりました

追記

[公式ドキュメント](https://developers.facebook.com/docs/ios/ios9)に、その他設定すべきスキーマ一覧があるので全部登録しましょう
# http通信を許可する

ここまででFacebookログインは動くようになるけど、コンソールに

```
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
```

が出まくる

これもiOS9でのセキュリティ強化起因で、デフォルトだとhttp通信が禁止されていて、FacebookSDKがなにかしらhttpで通信しようとしているのが失敗している

理想的には、Appleの意向に沿って極力httpsを使いつつ、どうしてもhttpを使わないといけないところだけ許可設定するべきかもしれないけど、
とりあえず

```
NSAppTransportSecurity (Dictionary)
  NSAllowsArbitraryLoads (Boolean): YES
```

の設定をInfo.plistに入れて、http通信を全許可にしてやれば解決

将来的には、Facebook側がhttpじゃなくhttps使うようにしてくれると嬉しい

追記

[公式ドキュメント](https://developers.facebook.com/docs/ios/ios9)にホワイトリストが載っているので、全許可じゃなくてこの通りに最小限の許可にしましょう

# 追記：bitcode OFF

bitcodeのことを忘れていたけど、

公式ドキュメント曰く、

> Is bitcode supported?
> 
> v4.6 and v3.24 of the SDK supports bitcode. If you are using earlier versions, you must disable bitcode.

v4.6以降はbitcode対応しているので、今ならbitcodeは有効にしたままでもOKの模様


# わかってないこと

Facebookのデベロッパーコンソールで、自分のAppを開いて、Settingのセクションに行くと

```
iOS
-----------------------------------
Single Sign On
will lanuch from iOS notofications
-----------------------------------
```

って項目があるんだけど、これはなにを制御してるんでしょうか

デフォルトでNOになっていて、別にNOのままでもFacebookアプリでのログインはできてるんだけど・・・