&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;
    }
}
}}

***GETでパラメータがセットされてない [#d15b26da]
-[[SA_OAuthTwitterEngine _sendRequestWithMethod:.... fails to apply params on GET · Issue #80 · bengottlieb/Twitter-OAuth-iPhone:https://github.com/bengottlieb/Twitter-OAuth-iPhone/issues/80]]おそらくバグ。
-以下のように修正。
#pre{{
if (!method && params) {
        fullPath = [self _queryStringWithBase:fullPath parameters:params prefixed:YES];
}
}}
*デモプロジェクトの仕組み [#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;
}

}}

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS