2017年9月21日木曜日

TwitterKit3でツイートできない -> できた

Twitterは公式SDK使用になった

iOS11にアップデートして、自分のアプリからツイッターに投稿しようとしたら、

if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeTwitter) { }
のところで値が false になっちまいまして…orz
むろん今まではうまくいってた。

どうやら、他社のサービスは他社のやり方でやれ、Appleはしらんわ…ということらしい。まあセキュリティの問題とかいろいろあるせいとは思うけど、めんどくさくなるのは勘弁してほしい。
ツイッター公式のTwitter kitというSDKがあって、今後はそっちを使わねばいけなくなるようだ。

詳しくは上のサイトのやり方に従って欲しいが、
  1. ツイッターにサインインしてアプリ情報などを入力
    1. 【重要】PermissionがRead & Writeになってないので、Update Settingsボタンを押してやって直す。(詳しくは後述)
  2. Twitter Kit SDKをダウンロードしてXcodeのプロジェクトにインストール(たいていはLinked Frameworks and Librariesに勝手に入ってくれると思う)
  3. Info.plistに項目追加
  4. ソースコードを編集
という手順になるようだ。

SafariServices.framework、AVFoundation.framework、CoreMedia.framework の3つも必要という情報もあったのだが、少なくともTwitterKit3、Xcode9、iOS11においては不要だった。

TwitterKitをゲット

さっそくツイッターのアプリ登録サイトに情報を入力してみたが…

ツイッターアカウントに電話番号情報が必要

…無情にもはじかれる。
You must add your mobile phone to your Twitter profile before creating an application. 
アプリケーションを作成する前に、携帯電話をTwitterプロファイルに追加する必要がありマース。
自分のツイッターアカウントに、セキュリティ用の携帯電話番号を登録しないといけないようだ。
普通にツイッター使うだけならいらないから無視してたんだけど、とうとうこの日がやってきてしまったか。

携帯電話番号登録のメリットとは!?

  • アカウントのセキュリティ
  • アカウント回復にかかる時間が短縮
  • ショートメールを介してTwitterを使用
  • 友だちがあなたのアカウントを見つけやすくなる
    • やめてくれ! むしろ見つけにくくしてくれ!
ツイッターがハッキングされて番号情報が漏れたら嫌だなあと思いつつ、やむをえずTwitter for iOSから携帯電話番号の登録をした。
登録した携帯にショートメールで認証番号が届くので、それを入力してやったらすぐにさっきのページが通ったよ。
これのConsumer Key (API Key)ってのを、後で自分のプロジェクトのInfo.plistに書き込む。
また、このConsumer Keyと、Keys And Access TokensタブにあるConsumer Secret (API Secret)をプロジェクトのAppDelegate内に書き込むことになる。

TwitterKit ダウンロード

現時点のバージョンは
CocoaPodsというiOSライブラリ管理ツールを使うと、手作業でいちいちダウンロードしてプロジェクトに追加して…ってやらずに済むらしいんだけど、最初にコマンドライン使ったりするようで、俺にとってはかえって敷居が高いので、今回は手作業でやってみる。

このページ中ほどの Install Twitter Kit Manuallyにある
1. Download and unzip Twitter Kit.
からダウンロード。

プロジェクトにインストール

この中の左3つを自分のプロジェクトにインストールしてやる。
右2つはTwitterKit.frameworkに内包されてるエイリアスなんだけど、別物と考えてそのままインストールする。

Info.plistの設定

Info.plistに以下の項目を追加する。
プロパティリストのままでもいいし、右クリックでOpen AsからSource Code表示にしてもいい。
// Info.plist
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>twitterkit-ここに取得したconsumerKeyを書く</string>
    </array>
  </dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>twitter</string>
    <string>twitterauth</string>
</array>

コードを書きませう

AppDelegate

TwitterKitのimportは言わずもがな。
import TwitterKit

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        //TwitterKit初期設定
        Twitter.sharedInstance().start(withConsumerKey: "ここにConsumerKeyを書く", consumerSecret: "ここにConsumer Secretを書く")
        
        return true
    }

//Twitterにログイン時に、認証トークンをディスクにリダイレクト(転送)し保存
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        
    return Twitter.sharedInstance().application(app, open: url, options: options)
    }

ツイートする処理

    //ツイッターへツイート
    @IBAction func actionBtn(_ sender: AnyObject) {
        //Twitterログイン認証トークンの有無を確認
        if Twitter.sharedInstance().sessionStore.hasLoggedInUsers() {
            //ツイート
            let composer = TWTRComposer()
            composer.setText("イニシャルテキスト") //初期テキスト
            composer.setURL(URL(string: "リンクのURL")) //リンク
            composer.setImage(UIImage(named: "リンクのURL")) //画像
            
            composer.show(from: self) { (result) in
                if result == TWTRComposerResult.done {
                    print("ツイートされた")
                } else {
                    print("ツイートできんかった")
                }
            }
        } else {
            //Twitterログイン処理
            Twitter.sharedInstance().logIn(completion: { (session, error) in
                if session != nil {
                    print("signed in as \(String(describing: session?.userName))")
                } else {
                    print("error: \(String(describing: error?.localizedDescription))")
                }
            })
        }
    }

うまくいかん!

以上でツイートできるはずなのだが、結果は失敗。

今までのSLComposeViewControllerのちっちゃいウィンドウと違い、もっとちゃんと大きなツイートのウィンドウが開き、画像もURLも貼られてるのに、ツイートボタンを押してもツイートされない。

エラーメッセージとしては以下のものが出るが、さっぱりわからん。
CredStore - performQuery - Error copying matching creds.  Error=-25300, query={
    class = inet;
    "m_Limit" = "m_LimitAll";
    ptcl = htps;
    "r_Attributes" = 1;
    sdmn = "https://api.twitter.com";
    srvr = "api.twitter.com";
    sync = syna;
}

Did encounter error sending Tweet: Error Domain=TWTRNetworkingErrorDomain Code=-1011 "Request failed: unauthorized (401)" UserInfo={NSLocalizedFailureReason=, TWTRNetworkingStatusCode=401, NSErrorFailingURLKey=https://api.twitter.com/1.1/statuses/update.json, NSLocalizedDescription=Request failed: unauthorized (401)}

[TwitterKit] Composer did fail: Error Domain=TWTRNetworkingErrorDomain Code=-1011 "Request failed: unauthorized (401)" UserInfo={NSLocalizedFailureReason=, TWTRNetworkingStatusCode=401, NSErrorFailingURLKey=https://api.twitter.com/1.1/statuses/update.json, NSLocalizedDescription=Request failed: unauthorized (401)}

調べると他の人も同じことで困ってる人がいるみたい。ここにも。ここにも。
ツイート内に「^ < > \ | ` または \r」の文字が使われていると401エラーになるそうだが、使ってないしなあ。

Fabricってのが必要?

2014年10月にTwitter社が発表したモバイルアプリ開発プラットフォーム。
安定性、利用者増、収益化、ユーザー認証の側面を網羅した開発キットだそうだ。
どうやらTwitterアプリを開発するにあたってこいつを使ってる人が多いらしいのだが、ツイートするだけとかならいらないのかもしれず、Twitter開発者のサイトでも「Upgrade from Fabric」として少ししか書かれてない様子。
もしどうしても必要なら調べて使うけど…??

うまくいった!

原因はTwitterKitのWebにある管理画面のパーミッションの設定で、表示と実際が違っていたためだ。
Read and Writeが嘘っぱちだった!
デフォルトの設定は表面上Read and Writeになってるんだけど、これが実際はRead onlyになっているものだから、ツイートしようとしても失敗してしまうのだ。
そりゃよっぽど注意しないと気づかねえってば。
責任は完全にTwitter社にある。

アカウント連携時の注意書きを見ると、ツイートできませんって!
それじゃツイートできるわきゃないよ。

直し方

管理画面でPermissionsタブの下の方にあるUpdate Settingsを押してやると、選ばれたとおりのPermissionに直ってくれる。
Fabricとかは全然いらない。
ツイッターゥァア゛ーーー
こんなもので何日間も悩ませやがって!

0 件のコメント:

コメントを投稿