Xamarinでツイートアプリつくるよ(4) Twitter認証PINなし そして絶望へ

ツイートアプリを名乗っているくせにTwitterのTの字すら出てこなかった当アプリですが、今回とうとうTwitter認証を実装します。
PINを使用せずに認証しようとしたらうっかり地獄の蓋を開けてしまいました

今回の記事を含むソースは以下に公開しています(APIキーなどを除く)
GitHub - reniris/NyanTweet: 定型短文ツイートプログラム

方法は以下を参照
wplogs.com
リソースファイルTwitterAPIKey.resxをNyanTweetプロジェクトへ追加して、AccessTokenAccessTokenSecretAPIKeyAPISecretを文字列リソースとして追加しておいてください。ここはGitHubには公開されていません

PINを使用して認証する場合

var session = CoreTweet.OAuth.Authorize(ConsumerKey, ConsumerSecret);
var url = session.AuthorizeUri;
Device.OpenUri(new Uri(url));

string PINcode; //ここにPINを入れる
tokens = CoreTweet.OAuth.GetTokens(session, PINcode);
var res = await tokens.Statuses.UpdateAsync(new { status = "にゃーん" });

こんな感じで簡単に書けるのですが、PINを使わない場合はそう簡単にいきません。
ググってもなかなかいい感じのコードが見つからなくて苦労しました。

PINを使わずに認証する場合はコールバックURLが必要です。Twitter Appshttps://apps.twitter.com/で適当なURLを設定しておいてください。プログラムで使うURLと違っていても大丈夫です。

ASP.NETでのコールバックURLは使用例が見つかったのですが、Xamarinではどうすればいいかわからずにしばらく悩む羽目になりました。
どうやらカスタムURLスキーマというものを使って自分自身を再起動すればいいようです。二重起動しないよう念のためLaunchModeをLaunchMode.SingleTaskにしておいてください。

カスタムURLスキーマの設定方法はちょまどさんのサイトを参考にしてください
chomado.com

Twitter認証をざっくり解説

  • ブラウザで認証ページを開いてコールバックでパラメータを取得

Device.OpenUri(new Uri(session.AuthorizeUri));でええやんと思っていたら結果を待ってくれないので、結果を待ってくれる機種依存コードを
xamarinhelp.com
forums.xamarin.com
を元に実装、だがどうやってもキャンセルが返ってくるという謎の現象に悩まされるため、OnActivityResultではなくOnResumeを使うことにした。
しかしsession.AuthorizeUriにはパラメータが入らないことに気づかず絶望、数日悩む羽目になった。
パラメータはコールバックのカスタムURLスキーマについているため、OnResumeからURLを返すように変更してようやくパラメータを取得できた。

  • クエリパラメータをパース

 ネットで見つけたコードをそのままコピペ。特に難しいことはない。

  • oauth_token と oauth_verifierを取得

  もう何も怖くない

var res = await t.Account.VerifyCredentialsAsync();
if(res.IsVerified == false) return null;

  とかやってたせいで常にnullが返っていた。最後の最後まで苦しめてくれます。

当方にはMaciPadもないのでiOS部分は実装していません。今回実装されたAndroid版をもとに誰か実装してください。

あと、今回のバージョンではアプリを再起動するたびに認証を求められます。この辺はあとで修正します。