[iOS] Twitterの公式SDK TwitterKit の利用

iOS 11から、Social.Frameworkが使えるような使えないような状態に。
いや、使えなくなる前提で動かないといけなそう。

Migrating from iOS Social Framework
https://dev.twitter.com/twitterkit/ios/migrate-social-framework

2017.9.26 [iOS] 現在のTwitter 7.7.2では、iOS 11で動作しないパターンがあります。
UIActivityViewController(下からメニューが出てきて選択するタイプ)を利用した投稿ではうまくいきますが、TwitterをSLComposeViewControllerで単体で呼び出す場合は、うまく動きません。

TwitterKit導入が必須になりそうです。

以下は全て Objective-C です。

Twitterの自分のアカウントにアプリを登録

まずはアプリの登録。これは、Web(CGIとか)や通常のアプリなどから、OAuth認証で利用する場合に以前からあるものです。
iOSにSocial機能が付く前は、ここで登録して利用してました。

Twitterアプリの追加
Application Management
https://apps.twitter.com

以前は、ささっと登録できましたが、現在はアカウントに電話番号を登録してあることが必須条件となっていました。
登録時に電話番号がないと、以下のページ参照を誘導されます。

アカウントへの携帯電話番号の登録
https://support.twitter.com/articles/20172611

レッツ登録。

最初のMigratingのページ内「Register an app in the Twitter apps dashboard」にも説明があります。

  • read-writeのパーミッション選択。
  • callback URLを埋めておく
  • 「Allow this application to be used to sign in with Twitter」のチェックを付ける。

TwitterKit導入!!

ダウンロードは、CocoaPodsを利用するか、直接ダウンロードして入れるか。

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

Podの場合–> Install Twitter Kit Using CocoaPods
直DLの場合–> Install Twitter Kit Manually
上記ページを参照。

設定で利用するのは、Twitterに登録したアプリConsumer KeyConsumer Secretの2つの文字列。

URLSchemeの設定

twitterアプリ、認証ページとのやりとりに利用されるアプリ固有のURL。
info.plistのURL types、URLSchemesに追加します。

追加する文字列は、
twitterkit-アプリのConsumer Key

このスキームで呼ばれた場合に、アプリ側で受け取れる記述をします。

TwitterKitのヘッダ

#import <TwitterKit/TwitterKit.h>

AppDelegateのopenURLへの追記。openURLが無ければ追加です。

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{

    if([[Twitter sharedInstance] application:app openURL:url options:options]){
        return true;
    }
    // 自前のURL処理
    ...
    return true;
}

TwitterKitのインスタンス初期化用に、didFinishLaunchingWithOptionsへの追記。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[Twitter sharedInstance] startWithConsumerKey:@"アプリのConsumer Key" consumerSecret:@"アプリのConsumer Secret"];
...

これで利用準備は完了です。

openURLが呼び出されないことがあるようです!!

投稿する!!!

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

    TWTRComposer *composer = [[TWTRComposer alloc] init];
    [composer setText:@"投稿するメッセージ"];
    [composer setImage:投稿するUIImage*];
    
    // Called from a UIViewController
    [composer showFromViewController:self completion:^(TWTRComposerResult result) {
        if (result == TWTRComposerResultCancelled) {
            NSLog(@"Tweet composition cancelled");
        }
        else {
            NSLog(@"Sending Tweet!");
        }
    }];

Twitterアプリがインストールされていると、そちらへ遷移し、アカウント利用許可が促されます。
一度許可すると、その後再度聞かれることはないです。
アプリ再インストールしても、聞かれません。
シミュレーターだとリセットでいいですが、実機の場合はログアウト処理でも別途用意しないとデバッグできなくなりそう。
キーチェーンあたりに保存されてるのでしょう。

ログアウト処理
Log In with Twitter
https://dev.twitter.com/twitterkit/ios/log-in-with-twitter

TWTRSessionStore *store = [[Twitter sharedInstance] sessionStore];
NSString *userID = store.session.userID;

[store logOutUserID:userID];

TWTRComposerではなく、TWTRComposerViewControllerを利用すると、呼び元のViewControllerを指定できました。
こちらを利用する場合は、事前にログイン有無を確認してほしいとの記載。

上記のCompose Tweetsのヘルプページのソースほぼそのままで利用できます。
サンプルではTWTRComposerViewControllerのemptyComposerを利用しているので、その部分を以下のように変更して使えますね。

        TWTRComposerViewController *composer = [[TWTRComposerViewController alloc] initWithInitialText:@"メッセージ" image:画像UIImage videoURL:nil];
        //composer.delegate = self;

TWTRComposerViewController部分、公式ドキュメントに不具合があります。
UIAlertControllerにボタン設定がないので、表示後に閉じれません。

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"No Twitter Accounts Available" message:@"You must log in before presenting a composer." preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];

↓ 変更

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"No Twitter Accounts Available" message:@"You must log in before presenting a composer." preferredStyle:UIAlertControllerStyleAlert];

// ボタン追加
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];

[self presentViewController:alert animated:YES completion:nil];

と、2パターンくらいありますが、最初のTWTRComposerだけの実装で事足りそうです(?)と、ちょっと思いましたが、そうでもなく。

ログインは最初のツイート時にできますが、ログアウトとアカウント変更ができません。
そのあたりは各自実装が必要となりますね。

複数アカウント対応した、投稿前の変更なども、アプリごとの実装に。
TwitterがOSに含まれない、初期の頃の実装方法に戻りました。

今までと比較すると、結構とても大変に。

複数アカウントを利用したい!!!

TWTRComposerやTWTRComposerViewControllerの最初の投稿時、勝手にひとつめのアカウント連携を行います。

さらに追加をしたい場合、ログイン処理を呼び出せば、TWTRSessionStoreに、UserSessionとして追加されていきます。
すでにSessionにある、同じアカウントを連携させた場合は、追加されませんでした。

ログイン処理
Log In Method – Log In with Twitter
https://dev.twitter.com/twitterkit/ios/log-in-with-twitter

// Objective-C
[[Twitter sharedInstance] logInWithCompletion:^(TWTRSession *session, NSError *error) {
if (session) {
NSLog(@”signed in as %@”, [session userName]);
} else {
NSLog(@”error: %@”, [error localizedDescription]);
}
}];

複数ユーザーは、TWTRSessionStoreのexistingUserSessionsで取得可能。

// Table表示の場合
// TableViewController のプロパティにでもしておいて
@property (nonatomic,strong) TWTRSessionStore *sessionStore;

    // sessionStore取得
    if ([[Twitter sharedInstance].sessionStore hasLoggedInUsers]) {
        self.sessionStore = [[Twitter sharedInstance] sessionStore];
    }

    // アカウント数取得
    count = [[self.sessionStore existingUserSessions] count];

    // TableCell表示用にユーザー情報取得など
    TWTRSession *session = [[self.sessionStore existingUserSessions] objectAtIndex:indexPath.row];
    TWTRAPIClient *client = [TWTRAPIClient clientWithCurrentUser];
    [client loadUserWithID:[session userID] completion:^(TWTRUser * _Nullable user, NSError * _Nullable error) {
        if(user != nil){
            NSLog(@"user %@ ",user);
        }
    }];

ツイート投稿後に、変更したアカウントが元に戻ってしまう!

ツイートにTWTRComposerViewControllerを利用し、TWTRComposerViewControllerDelegateのcomposerDidSucceedでどうにか変更できました。

もっとシンプルなやり方あったら教えてください!!!

- (void)composerDidSucceed:(TWTRComposerViewController *)controller withTweet:(TWTRTweet *)tweet{
    TWTRUser *author = tweet.author;
    TWTRSessionStore *store = [[Twitter sharedInstance] sessionStore];
    NSArray *arr = store.existingUserSessions;
    TWTRSession *currentSession = nil;
    for(TWTRSession *s in arr){
        if([s.userID isEqualToString:author.userID]){
            currentSession = s;
            break;
        }
    }
    if(currentSession){
        // ツイート成功したユーザーを現在のsessionへ保存
        [[[Twitter sharedInstance] sessionStore] saveSession:currentSession completion:^(id<TWTRAuthSession>  _Nullable session, NSError * _Nullable error) {
            // 特になし
        }];
    }
}

Twitter本体の不具合が改善すれば、Social.Frameworkは今後もしばらくは使えるのかもしれません。
Twitter Kitの導入は、早めにやっておくか否かというところでしょうか。

公式のフォーラム
Twitter Developers
https://twittercommunity.com/c/publisher/twitter

顔文字がツイートできないなと思ったら、改善されていない不具合ですね。結構まずいかもしれない。
^ < > \ | ` tweets error
https://twittercommunity.com/t/tweets-error/73153

これは多分エスケープの種類が足りていないだけと思われるけれど。
これは、日本ではレアケースではなく、とても厳しい。。。

試したところ、半角の『^><』の3種がとりあえずダメですね。
とりあえず入れないとうまく動かないので、導入は進めてますが。

他の参考となる記事

Qiita
iOS11のTwitter投稿対応(Social.framework → TwitterKit)
swiftでのサンプルがありました!

FacebookもSDK対応ですかね。。
[FacebookSDK] 画像やリンクの投稿

シェアする

  • このエントリーをはてなブックマークに追加

フォロミー

コメントをどうぞ

メールアドレスが公開されることはありません。