Edited at

verifyCredentialsWithSuccessBlock:errorBlock:がnilのトークンを返してくるときは[ACAccountStore renewCredentialsForAccount:completion:]しないといけない

More than 5 years have passed since last update.

TwitterのAPIを利用するiOSアプリはSTTwitter を利用すると簡単に作ることが出来る。ところで、このSTTwitterの verifyCredentialsWithSuccessBlock:errorBlock: というメソッドが、successBlockを実行するにもかかわらず引数のoauthTokenにnilを渡してくるので困っていた。調べるとちゃんとソースコードに注意書きがしてあったけど、自分のように気づかない人も多そうなのでメモしておく。

この挙動はiOSにTwitterアカウントが紐付いているけど、パスワードが設定されてないときのみ起きるらしく、iOSのバグ?っぽい。

対応策としては

[ACAccountStore renewCredentialsForAccount:completion:] を呼んでユーザにパスワードを設定してもらうことになる。

具体的なコードは以下の様な感じ

[api postReverseAuthAccessTokenWithAuthenticationHeader:authenticationHeader successBlock:^(NSString *oAuthToken, NSString *oAuthTokenSecret, NSString *userID, NSString *screenName) {

if (!oAuthTokenSecret || !oAuthToken) {
// TwitterのパスワードがOSに設定されてないのでACAccountStoreを使ってユーザを設定画面に誘導する
ACAccountStore* accountStore = [ACAccountStore new];
ACAccountType* twitterType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
ACAccount *twitterAccount = [[accountStore accountsWithAccountType:twitterType] firstObject];
[accountStore renewCredentialsForAccount:twitterAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
// OSのダイアログがでて、ユーザは設定画面に飛ぶことができる。ユーザの行動に応じてACAccountCredentialRenewResultRenewed, ACAccountCredentialRenewResultRejected, ACAccountCredentialRenewResultFailedのどれかがかえるはずだけど、自分がデバッグしてた時は設定画面に飛んだ時も ACAccountCredentialRenewResultRejectedが渡ってきた、よくわからない。
}];
} else {
// 無事にtokenがとれた場合の処理
}
}];