2009-12-02 102 views
3

我想實現Twitter的自定義登錄視圖(我不想那個UIWebView)。 我已經下載了很多課程,並且我到目前爲止有噩夢與此。現在我正在努力推動Twitter + oAuth的工作。這裏的演示代碼(即工作):Twitter + oAuth噩夢

_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self]; 
_engine.consumerKey = kOAuthConsumerKey; 
_engine.consumerSecret = kOAuthConsumerSecret; 

[_engine requestRequestToken]; 

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定製UITextFields。所以我試圖這樣:

_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self]; 
_engine.consumerKey = kOAuthConsumerKey; 
_engine.consumerSecret = kOAuthConsumerSecret; 

[_engine requestRequestToken]; 
[_engine requestAccessToken]; 
[_engine setUsername:@"username" password:@"password"]; 
[_engine sendUpdate:@"tweet"]; 

但我不斷收到錯誤401.我可能錯過了一步。任何人?

回答

1

我認爲你缺少一點就在這裏,SA_OAuthTwitterEngine.m:103:

//This generates a URL request that can be passed to a UIWebView. It will open a page in which the user must enter their Twitter creds to validate 
- (NSURLRequest *) authorizeURLRequest { 
     if (!_requestToken.key && _requestToken.secret) return nil;  // we need a valid request token to generate the URL 

     OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL: self.authorizeURL consumer: nil token: _requestToken realm: nil signatureProvider: nil] autorelease];  

     [request setParameters: [NSArray arrayWithObject: [[[OARequestParameter alloc] initWithName: @"oauth_token" value: _requestToken.key] autorelease]]]; 
     return request; 
} 

您將有「假」這個用戶登錄了自己,我相信通過發送Twitter上登錄憑證作爲單獨的請求。看起來你所調用的setUsername方法實際上在接收到有效的訪問令牌後被稱爲post操作。請參閱SA_OAuthTwitterEngine。L:185

// 
// access token callback 
// when twitter sends us an access token this callback will fire 
// we store it in our ivar as well as writing it to the keychain 
// 
- (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 class] setUsername: username password: nil]; 
       if ([_delegate respondsToSelector: @selector(storeCachedTwitterOAuthData:forUsername:)]) [(id) _delegate storeCachedTwitterOAuthData: dataString forUsername: username]; 
     } 

     [_accessToken release]; 
     _accessToken = [[OAToken alloc] initWithHTTPResponseBody:dataString]; 
} 

因此,步驟如下:

  1. 請求請求令牌
  2. 僞造用戶登錄到Twitter和讓圖釘值
  3. 設置引腳上的發動機
  4. 請求訪問令牌

您可以看到ËSA_OAuthTwitterController解析銷出SA_OAuthTwitterController.m web視圖內容:156

#pragma mark Webview Delegate stuff 
- (void) webViewDidFinishLoad: (UIWebView *) webView { 
     NSError *error; 
     NSString *path = [[NSBundle mainBundle] pathForResource: @"jQueryInject" ofType: @"txt"]; 
    NSString *dataSource = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; 

    if (dataSource == nil) { 
     NSLog(@"An error occured while processing the jQueryInject file"); 
    } 

     [_webView stringByEvaluatingJavaScriptFromString:dataSource]; //This line injects the jQuery to make it look better 

     NSString          *authPin = [[_webView stringByEvaluatingJavaScriptFromString: @"document.getElementById('oauth_pin').innerHTML"] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

     if (authPin.length == 0) authPin = [[_webView stringByEvaluatingJavaScriptFromString: @"document.getElementById('oauth_pin').getElementsByTagName('a')[0].innerHTML"] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

     [_activityIndicator stopAnimating]; 
     if (authPin.length) { 
       [self gotPin: authPin]; 
     } 
     if ([_webView isLoading] || authPin.length) { 
       [_webView setHidden:YES]; 
     } else { 
       [_webView setHidden:NO]; 
     } 
} 

希望這會有所幫助。

+0

非常感謝你的回答。但是我最終使用了UIWebView。我認爲大多數應用程序都在使用這些UITextField上的oAuth,但它們不是。因此,「通過API發佈」。 – samvermette 2009-12-05 08:23:00

2

您正在消除的視圖控制器加載webview,提示用戶使用twitter驗證您的應用程序。如果你沒有用戶認證,你將無法進行認證的Twitter電話。有一種方法可以做你想做的事情,但是,你必須自己完成所有的OAuth步驟。下面是從一個different web service (Vimeo)指定的步驟,但同樣的規則:

  1. 您的應用程序將與您的用戶密鑰的請求 ,並與你的消費者的祕密簽訂 ,對於 一種叫做請求令牌。如果 我們驗證您的應用程序 正確,我們會發送回 請求令牌和令牌密鑰。

  2. 然後,您將創建一個鏈接供用戶用請求令牌點擊。

  3. 當用戶訪問Vimeo時,系統會提示他們允許您的 應用程序訪問其帳戶。 如果他們點擊是,我們會將它們 發送回您的應用程序,以及 驗證程序。

  4. 然後,您會使用請求令牌,驗證和令牌機密使
    再次調用我們獲得訪問令牌 。訪問令牌是您將用來訪問Vimeo上的用戶的 信息的密碼 。

OAuth是在臀部一個真正的痛苦,那麼好的運氣了。 ;-)

1

您必須使用xAuth來定製用戶/密碼控件。但它需要Twitter的許可。