- 追加された行はこの色です。
- 削除された行はこの色です。
&tag(Twitter-OAuth-iPhone);
*目次 [#tf833dcf]
#contents
*参考情報 [#s34a9dab]
-[[bengottlieb/Twitter-OAuth-iPhone · GitHub:https://github.com/bengottlieb/Twitter-OAuth-iPhone]]
*デモプロジェクトのビルド [#b2aeb473]
-zipをダウンロードして展開。Demoフォルダの下にプロジェクトがある。
-OAuthTwitterDemoViewController.mのConsumerKeyとConsumerSecretを設定
#pre{{
#define kOAuthConsumerKey @"" //REPLACE ME
#define kOAuthConsumerSecret @"" //REPLACE ME
}}
**トラブルシューティング [#j72d11fa]
*** "Select and Copy the PIN"って何? [#m52c43f2]
-callbackurlがセットされてるとうまくいかないのかも。
-[[Issue for Twitter applications with callback URL set · Issue #79 · bengottlieb/Twitter-OAuth-iPhone:https://github.com/bengottlieb/Twitter-OAuth-iPhone/issues/79]]に従ってSA_OAuthTwitterViewController.m を修正。
#pre{{
- (void) webViewDidFinishLoad: (UIWebView *) webView {
_loading = NO;
//[self performInjection];
if (_firstLoad) {
[_webView performSelector: @selector(stringByEvaluatingJavaScriptFromString:) withObject: @"window.scrollBy(0,200)" afterDelay: 0];
_firstLoad = NO;
} else {
// This else clause modified to work with twitter apps that have the callback URL set: https://dev.twitter.com/apps/
// Bug details: https://github.com/bengottlieb/Twitter-OAuth-iPhone/issues/79
[_engine requestAccessToken];
if ([_delegate respondsToSelector: @selector(OAuthTwitterController:authenticatedWithUsername:)])
[_delegate OAuthTwitterController: self authenticatedWithUsername: _engine.username];
[self dismissModalViewControllerAnimated:YES];
}
[UIView beginAnimations: nil context: nil];
_blockerView.alpha = 0.0;
[UIView commitAnimations];
if ([_webView isLoading]) {
_webView.alpha = 0.0;
} else {
_webView.alpha = 1.0;
}
}
}}
*デモプロジェクトの仕組み [#wa6a5550]
**起動時 [#s072c155]
-OAuthTwitterDemoViewControllerのviewDidApperから開始。controllerがnilでないならば認証用のWebViewが表示されることになる。
#pre{{
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
if (controller)
[self presentModalViewController: controller animated: YES];
else {
[_engine sendUpdate: [NSString stringWithFormat: @"Already Updated. %@", [NSDate date]]];
}
}}
-SA_OAuthTwitterControllerのcontrollerToEnterCredentialsWithTwitterEngineではSA_OAuthTwitterEngineのisAuthorizedにより認証が必要かどうかの判定を行っている。
#pre{{
- (BOOL) isAuthorized {
if (_accessToken.key && _accessToken.secret) return YES;
//first, check for cached creds
NSString *accessTokenString = [_delegate respondsToSelector: @selector(cachedTwitterOAuthDataForUsername:)] ? [(id) _delegate cachedTwitterOAuthDataForUsername: self.username] : @"";
if (accessTokenString.length) {
[_accessToken release];
_accessToken = [[OAToken alloc] initWithHTTPResponseBody: accessTokenString];
[self setUsername: [self extractUsernameFromHTTPBody: accessTokenString] password: nil];
if (_accessToken.key && _accessToken.secret) return YES;
}
[_accessToken release]; // no access token found. create a new empty one
_accessToken = [[OAToken alloc] initWithKey: nil secret: nil];
return NO;
}
}}
-OAuthTwitterDemoViewControllerのcachedTwitterOAuthDataForUsernameを利用し、[NSUserDefaults standardUserDefaults]からキャッシュデータを取得。キャッシュされているのは以下のような内容
oauth_token=xxxxxxxxxxx&oauth_token_secret=yyyyyyyyyyyyyyyyyyyyyyy&user_id=99999999&screen_name=xxxxxxx
-とりだしたデータからOATokenをアロケートし保存。リクエストごとにセットされる。
**認証実証時 [#l3ad4f6f]
-SA_OAuthTwitterEngine.mのsetAccessToken:withData:が呼び出され、さらに中で、_delegate storeCachedTwitterOAuthDataが呼び出されデータがキャッシュされる。
#pre{{
- (void) setAccessToken: (OAServiceTicket *) ticket withData: (NSData *) data {
if (!ticket.didSucceed || !data) return;
NSString *dataString = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];
if (!dataString) return;
if (self.pin.length && [dataString rangeOfString: @"oauth_verifier"].location == NSNotFound) dataString = [dataString stringByAppendingFormat: @"&oauth_verifier=%@", self.pin];
NSString *username = [self extractUsernameFromHTTPBody:dataString];
if (username.length > 0) {
[self setUsername: username password: nil];
if ([_delegate respondsToSelector: @selector(storeCachedTwitterOAuthData:forUsername:)]) [(id) _delegate storeCachedTwitterOAuthData: dataString forUsername: username];
}
[_accessToken release];
_accessToken = [[OAToken alloc] initWithHTTPResponseBody:dataString];
}
}}
-ちなみに、username(=@xxxxで使われるscreen_name)は以下のメソッドで取り出されている。
#pre{{
- (NSString *) extractUsernameFromHTTPBody: (NSString *) body {
if (!body) return nil;
NSArray *tuples = [body componentsSeparatedByString: @"&"];
if (tuples.count < 1) return nil;
for (NSString *tuple in tuples) {
NSArray *keyValueArray = [tuple componentsSeparatedByString: @"="];
if (keyValueArray.count == 2) {
NSString *key = [keyValueArray objectAtIndex: 0];
NSString *value = [keyValueArray objectAtIndex: 1];
if ([key isEqualToString:@"screen_name"]) return value;
}
}
return nil;
}
}}