iPhone
Twitter
iOS
ios11
TwitterKit

iOS11向けにSocial.frameworkを使わないTwitter投稿

More than 1 year has passed since last update.

基本的にTwitter公式にある情報です。

この記事を読むよりも公式の情報をちゃんと読んだ方がいいと思います。

■ Migrating from iOS Social Framework

https://dev.twitter.com/twitterkit/ios/migrate-social-framework

以下は日本語が読みたい人向けに。 (※17/6/26の内容を元にしています)

6/27 追記

説明の中で使用されているTwitter Kit v3.0はiOS9+をサポート条件にしています。

そのため、アプリのサポートバージョンをiOS9以降に更新してから利用しましょう。

https://dev.twitter.com/twitterkit/ios/upgrading


概要

例年なら9月上旬くらいには公開されるiOS11からはSocial.frameworkを通じてTwitterを利用できなくなります。

その代わりに、TwitterKit3を利用してツイートやユーザーのログイン、TwitterAPIを使用します。


TwitterKit3

インストールページからダウンロードすることもできますが、私はとりあえずCocoaPodsでやります。


Podfile

pod 'TwitterKit'



アプリケーションの登録

開発者用に利用するTwitterアカウントで電話番号の認証を済ませた上で、

Twitterアプリのダッシュボードからアプリケーションを作成します。


  1. 読み書き可能なアプリケーションで作成(Access level: Read and write)

  2. 互換性のため、コールバックURLを設定。使用するつもりがないならhttps://example.comでも設定しておけと書いてある。

  3. SettingsからAllow this application to be used to Sign in with Twitterにチェックを入れる


TwitterKitの初期化処理を設定


URLスキームの追加


info.plist

<key>CFBundleURLTypes</key>

<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>twitterkit-{yourConsumerKey}</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>twitter</string>
<string>twitterauth</string>
</array>

6/29 追記

上記の設定を行なっていても、以下のようなエラーが出力されることがあります。

Terminating app due to uncaught exception 'TWTRInvalidInitializationException', 

reason: 'Attempt made to Log in or Like a Tweet without a valid Twitter Kit URL Scheme set up in the app settings.
Please see https://dev.twitter.com/twitterkit/ios/installation for more info.'

原因はTwitterKitの不具合で、CFBundleURLSchemesの先頭に追加しないと判定されないようです。(v3.0.3時点)

https://twittercommunity.com/t/twitterkit-v3-causes-exception-upon-sign-in-on-ios/88143/7


AppDelegateにハンドラを追加


appDelegate.swift

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

if Twitter.sharedInstance().application(app, open: url, options: options) {
return true
}
// Your other open URL handlers follow […]
}


Twitter.startを呼ぶ


appDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

Twitter.sharedInstance().start(withConsumerKey: "example-hPpFPVQ64pThkM0", consumerSecret: "exmaple-ovAqziZzzHpU5F163Qg9mj")
return true
}


Twitterでログイン


 ACAccountStore.requestAccessToAccounts -> Twitter.logIn


ACAccountStore

let account = ACAccountStore()

let accountType = account.accountType(withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)

account.requestAccessToAccounts(with: accountType, options: nil, completion: {(success, error) in
if success {
if let twitterAccount = account.accounts(with: accountType).last as? ACAccount {
print("signed in as \(twitterAccount.userame)");
}
}
})


TwitterKitを利用した場合


TwitterKit

Twitter.sharedInstance().logIn(completion: { (session, error) in

if let sess = session {
print("signed in as \(sess.userName)");
} else {
print("error: \(error.localizedDescription)");
}
}


ACAccountStore.accounts -> TWTRSessionStore

アプリケーションを認証すると、TwitterKitがセッションを保存します。

ログイン後は、Twitter.sharedInstance().sessionStore.session()を利用すれば現在の認証済みセッションを取得することができます。

アプリにセッションがあるかどうかはTwitter.sharedInstance().sessionStore.hasLoggedInUsers()でテストできます。

https://dev.twitter.com/twitterkit/ios/log-in-with-twitter


ツイートする

TwitterKitを利用してリンク、画像、ビデオの共有が行えます。


SLComposeViewController -> TWTRComposer


SLComposerViewController

if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter) {

let composer = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
composer.setInitialText("Hello Twitter!")
composer.addImage(UIImage(named: "hello"))
composer.addURL(URL(string: "https://dev.twitter.com"))
self.presentViewController(socialController, animated: true, completion: nil)
}

TwitterKitではTWTRComposerで同じ機能を提供します。


TWTRComposer

let composer = TWTRComposer()

composer.setText("Hello Twitter!")
composer.setImage(UIImage(named: "hello"))
composer.setUrl(URL(string: "https://dev.twitter.com"))
composer.show(from: self, completion: nil)

ビデオの投稿なども含めたツイートの構成については、TWTRComposeViewControllerに関するドキュメントを参照

https://dev.twitter.com/twitterkit/ios/compose-tweets


TwitterAPIを利用する

上記の手順にしたがってユーザーの承認を更新し、OAuthで署名されたリクエストを使います。


SLRequest -> TWTRAPIClient


SLRequest

let account = ACAccountStore()

let accountType = account.accountType(withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)

account.requestAccessToAccounts(with: accountType, options: nil, completion: {(success, error) in
if success {
if let twitterAccount = account.accounts(with: accountType).last as? ACAccount
let statusesShowEndpoint = "https://api.twitter.com/1.1/statuses/show.json"
let params = ["id": "20"]

let request = SLRequest(forServiceType: SLServiceTypeTwitter,
requestMethod: SLRequestMethod.GET,
URL: URL(string: statusesShowEndpoint),
parameters: params)
request?.account = twitterAccount
request?.perform(handler: {(responseData, urlResponse, error) in
if let err = error {
print("Error : \(err.localizedDescription)")
} else {
print("The first Tweet: \(responseData)")
}
})
}
}
})


TwitterKit


TWTRAPIClient

if let twitterAccountId = Twitter.sharedInstance().sessionStore.session()?.userID {

let client = TWTRAPIClient(userID: twitterAccountId)
let statusesShowEndpoint = "https://api.twitter.com/1.1/statuses/show.json"
let params = ["id": "20"]
var clientError : NSError?

let request = client.urlRequest(withMethod: "GET", url: statusesShowEndpoint, parameters: params, error: &clientError)

client.sendTwitterRequest(request) { (response, responseData, error) -> Void in
if let err = error {
print("Error: \(err.localizedDescription)")
} else {
print("The first Tweet: \(responseData)")
}
}
} else {
// Not logged in
}


詳しくはやっぱり公式ドキュメント見た方がいいです。