先日「TwitterKitを使ってのログインで失敗する」という記事を書きました。Twitterにログインするだけのコードを書くのが随分と簡単になりました。
今日はFacebookにログインする処理を書いてみましたが、やはり少しハマってしまいました。導入ドキュメントを読んでないのがバレてしまう……
Facebook SDKを導入する
こちらも最近の流れに乗ってかCocoaPodsを使うだけで公式SDKが導入できてしまいます。Podfileに
pod 'FBSDKCoreKit' pod 'FBSDKShareKit' pod 'FBSDKLoginKit'
と書いてpod install
でインストールします。
次に、Info.plistに下図のように定義を追加します。
SourceCodeモードで表示させると下記の通りです。
<key>FacebookAppID</key> <string>xxxxxxxxxxxxxxx</string> <key>FacebookDisplayName</key> <string>$(PRODUCT_NAME)</string> <key>LSApplicationQueriesSchemes</key> <array> <string>fbapi</string> <string>fb-messenger-api</string> <string>fbauth2</string> <string>fbshareextension</string> </array>
最後に呼び元のアプリ(私が実装しているアプリ)に戻ってくるためにカスタムURLスキームを追加します。
ログイン処理は以下のように書くことができます。かなりシンプルで良い感じです。
func facebookLoginAction() { let login = FBSDKLoginManager() login.logInWithReadPermissions(["public_profile", "email"], fromViewController: self) { (result: FBSDKLoginManagerLoginResult!, error: NSError!) in if error != nil { // 失敗!! } else if result.isCancelled { // キャンセル } else { // 成功 } } }
logInWithReadPermissionsメソッド
を実行するとiOS 8とiOS 9とで挙動が異なりますが、それぞれで正しくログインすることができませんでした。
ログインに失敗してしまう
iOSシミュレータを使ってのログインテストで、iOS 8.4、iOS 9のそれぞれで問題が発生することがわかりました。それぞれの現象について書きます。
iOS 8でログインができない!
iPhone 6/iOS 8のiOSシミュレータでログインのテストをしてみました。iOS 8ではlogInWithReadPermissionsメソッド
を実行するとブラウザが起動します。
IDとパスワードを入力してログインに成功して、アプリ連携を許可するを選択すると、呼び元のアプリに戻るのですが、result.isCancelled
の値が常にtrue
になってしまいます。
エラーは発生していない(NSErrorはnilになっていてエラー情報を持たない)のですが、アクセストークンは取得できずユーザーによるキャンセル状態になってしまいます。
iOS 9でログインができない!
iPhone 6s/iOS 9のiOSシミュレータでログインのテストをしてみました。iOS 9ではlogInWithReadPermissionsメソッド
を実行するとSFSafariViewControllerを使った画面遷移がおこなわれます。
SFSafariViewController上でIDとパスワードを入力してログインに成功して、アプリ連携を許可するを選択しても呼び出し元のアプリに戻ってくれませんでした。logInWithReadPermissionsメソッド
で指定しているクロージャも呼ばれていない状態です。
解決策
両方ともAppDelegateにFacebook SDKのための実装をしていなかったのが原因で問題が発生していました。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { FBSDKSettings.setAppID("xxxxxxxxxxxxxx") return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) } func applicationDidBecomeActive(application: UIApplication) { FBSDKAppEvents.activateApp() } func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool { return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation) }
これで前述した問題は発生しなくなり正しくログイン処理がおこなわれるようになりました。
関連記事
この他にもiOSアプリ開発で見つけたネタや悩んだ内容など紹介しています。Tipsをまとめておりますのでこちらのページをご参照ください。