【iOS】TwitterKitじゃなくて「Swifter」でTwitterログインする


新規アプリを作るときは、FirebaseAuthを使ってログインを実装することが多く、FacebookログインやTwitterログインを良く使います。

FacebookのiOS SDKは安定して使いやすいのですが、Twitter公式がかつてメンテナンスしていたTwitterKitは安定していなくて、色々バグが多いです。 (2018年10月に公式サポートが終了している)

ということで、今回はiOSでTwitterログインをする際にTwitterKitよりもオススメなSwifterを紹介します。

mattdonnelly/Swifter

インストール

https://hawksnowlog.blogspot.com/2016/09/tweet-with-swifter.html の記事が詳しいです。cocoapodsなどは対応していないので、Embedded Binariesとして追加しましょう。

SwifterでTwitterログイン

あらかじめTwitter Developerでアプリを作成し、consumerKeyとconsumerSecretを取得しといてください。

ViewController.swift
import Swifter

let swifter = Swifter(
    consumerKey: "<--Twitter Developerで作ったconsumerKey-->",
    consumerSecret: "<--Twitter Developerで作ったconsumerSecret-->"
)
swifter.authorize(
    withCallback: "<-アプリに帰ってくるためのコールバックURL->",
    presentingFrom: self,
    success: { accessToken, response in
        // このあとaccessToken使うよ
}, failure: { error in
    print(error)
})

成功すると、accessTokenが取得できるので、これをこの後使います。(次の章)

safariに飛んでログインした後に戻ってこれるように、AppDelegateには以下にように書きます。

AppDelegate.swift
import Swifter

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    return Swifter.handleOpenURL(url, callbackURL: "<-アプリに帰ってくるためのコールバックURL->")
}

追記

Loginする画面のViewControllerをSFSafariViewControllerDelegateに準拠させることを忘れずに!準拠させることでアプリ内でsafariが開けます。(準拠しないと外部のsafariに飛んで、a poor user experienceという理由でアプリがAppleにリジェクトされました)

ViewController.swift
import SafariServices

class ViewController: UIViewController, SFSafariViewControllerDelegate {

}

accessTokenの使い方

先ほどのauthorizeメソッドでaccessTokenが取得できます。これはStringではなく、Credential.OAuthAccessTokenというSwifterが作っている型で、いくつかパラメータを持ちます。

今回はここからkeyとsecretを取得します。

authorizeメソッドのsuccessの中
guard let accessToken = accessToken else {
    return
}
let oAuthToken = accessToken.key
let secret = accessToken.secret

ローカルで使う

例えばローカルでこのままSwifterの機能であるTwitter投稿をしたりしたい場合は、次からログインなしでできるように、このaccessToken.keyaccessToken.secretをUserDefaults等に入れておきます。

そしたら次から以下のようにswifterをinitして使えます。

let swifter = Swifter(
    consumerKey: "<--Twitter Developerで作ったconsumerKey-->",
    consumerSecret: "<--Twitter Developerで作ったconsumerSecret-->",
    oauthToken: oAuthToken, //ローカルに保存していたやつ
    oauthTokenSecret: secret //ローカルに保存していたやつ
)
swifter.postTweet(status: shareText, success: { status in

}, failure: { error in

})

Firebaseでログインする

FirebaseAuthでログインしたい場合は、FirebaseAuthのTwitterAuthProvider.credentialを作ってログインできます。

import Firebase

let credential = TwitterAuthProvider.credential(
    withToken: oAuthToken,
    secret: secret
)
Auth.auth().signIn(with: credential, completion: { (authResult, error) in

})

Firebase公式ドキュメントでは、twitterKitでこのauthTokensecretを取得していますが、Swifterで取得したものをここに入れればあとは同様の手順でいけます。

TwitterKitとの違い

TwitterKitはTwitterネイティブアプリがある場合、アプリに飛んで認証しますが、Swifterの場合はアプリがあってもSafariを起動して認証します。

また、TwitterKitのTwitter投稿は専用のViewControllerを出す必要がありますが、Swifterならコードだけで完結します。

以上です。詳しくは、mattdonnelly/SwifterのリポジトリのサンプルコードやReadmeへ。

関連リンク

https://firebase.google.com/docs/auth/ios/twitter-login?hl=ja
https://hawksnowlog.blogspot.com/2016/09/tweet-with-swifter.html
https://github.com/mattdonnelly/Swifter