2010-09-22 39 views
3

我想製作一個在Google Reader API上使用的應用。但是我發現它沒有官方的API--根據App Store指導方針/批准,使用非官方API有什麼問題嗎?其他應用程序(Reeder等)會使用它嗎?在iPhone應用中使用Google Reader API和OAuth

什麼是登錄的最佳方法? OAuth是優先選擇的方法嗎?使用Janrain是個好主意嗎?

回答

6

Ive自從發現此問題後:「Google Data APIs Objective-C客戶端庫提供了一個iPhone靜態庫,一個Mac OS X框架以及通過Google Data API輕鬆訪問數據的源代碼。」 code.google.com/p/gdata-objectivec-client - 這太棒了! 但它不包含Reader API(因爲它尚未發佈)。

我已經能夠通過改變訪問API(在OAuthSampleTouch例子)

NSString *scope = @"http://www.google.com/m8/feeds/"; 

在OAuthSampleRootViewControllerTouch.m到

NSString *scope = @"http://www.google.com/reader/api/*"; 

urlStr = @"http://www.google.com/m8/feeds/contacts/default/thin"; 

urlStr = @"http://www.google.com/reader/atom/user/-/label/Design"; 

其中設計是一個文件夾名稱 - 檢查此http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI它的一個很大的幫助。


更新

因爲我已經發現,這種技術是最好的/最輕/-複雜少: Native Google Reader iPhone Application

7

坦率地說,蘋果不在乎你是否使用Google的非官方API。

我爲一位使用Google Reader進行同步的RSS閱讀器應用程序的客戶工作。我們沒有使用OAuth,而是使用標準HTTP登錄,它會返回一個Cookie,您必須提取一個令牌才能連續調用各種閱讀器URL。

我可以從我的(舊)驗證概念應用程序發佈您的登錄代碼。 它使用ASIHTTP和一些自定義字符串類別。這個想法是發送一個登錄請求,獲取響應並從響應的cookie頭中提取會話ID /授權碼。然後,您可以使用該會話ID /授權碼進行連續呼叫。

#pragma mark - 
#pragma mark login 

//this is your sessionID token you get from the login 
//use this in consecutive calls to google reader 
//this method returns you the header string you have to add to your request 
//[request addRequestHeader: @"Cookie" value: [self sidHeader]]; 
- (NSString *) sidHeader 
{ 
    return [NSString stringWithFormat: @"SID=%@", [self sid]]; 
} 

- (NSString *) authHeader 
{ 
    return [NSString stringWithFormat: @"GoogleLogin auth=%@",[self auth]]; 
} 


//login to your google account and get the session ID 
- (void) login 
{ 
    NSString *username = @"[email protected]"; 
    NSString *password = @"mypassword123"; 
    NSString *loginUrl = @"https://www.google.com/accounts/ClientLogin?client=NNW-Mac"; 
    NSString *source = @"NNW-Mac"; //let's fake NetNewsWire 
    NSString *continueUrl = @"http://www.google.com"; 

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString: loginUrl]]; // log in & get cookies 
    [request addRequestHeader: @"User-Agent" value: @"NetNewsWire/3.2b25 (Mac OS X; http://www.newsgator.com/Individuals/NetNewsWire/)"]; 

    [request setPostValue: username forKey: @"Email"]; 
    [request setPostValue: password forKey: @"Passwd"]; 
    [request setPostValue: @"reader" forKey: @"service"]; 
    [request setPostValue: source forKey: @"source"]; 
    [request setPostValue: continueUrl forKey: @"continue"]; 

    [request setDelegate: self]; 
    [request setDidFailSelector: @selector(loginRequestFailed:)]; 
    [request setDidFinishSelector: @selector(loginRequestFinished:)]; 

    [request start]; 
} 

-(void)loginRequestFinished:(ASIHTTPRequest *)request 
{ 
    NSString *responseString = [request responseString]; 

    //login failed 
    if ([responseString containsString: @"Error=BadAuthentication" ignoringCase: YES]) 
    { 
     [self setLastError: [self errorWithDescription: @"Bad Username/Passsword" code: 0x001 andErrorLevel: 0x00]]; 

     if ([delegate respondsToSelector: @selector(gReaderLoginDidFail:)]) 
     { 
      [delegate gReaderLoginDidFail: self]; 
     } 

     return NO; 
    } 

    //captcha required 
    if ([responseString containsString: @"CaptchaRequired" ignoringCase: YES]) 
    { 
     [self setLastError: [self errorWithDescription: @"Captcha Required" code: 0x001 andErrorLevel: 0x00]]; 

     if ([delegate respondsToSelector: @selector(gReaderLoginDidFail:)]) 
     { 
      [delegate gReaderLoginDidFail: self]; 
     } 

     return NO; 
    } 

    //extract SID + auth 
    NSArray *respArray = [responseString componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]]; 

    NSString *sidString = [respArray objectAtIndex: 0]; 
    sidString = [sidString stringByReplacingOccurrencesOfString: @"SID=" withString: @""]; 
    [self setSid: sidString]; 

NSString *authString = [respArray objectAtIndex: 2]; 
authString = [authString stringByReplacingOccurrencesOfString: @"Auth=" withString: @""]; 
[self setAuth: authString]; 
    //mesage delegate of success 
    if ([delegate respondsToSelector: @selector(gReaderLoginDidSucceed:)]) 
    { 
     [delegate gReaderLoginDidSucceed: self]; 
    } 

    return YES; 
} 

- (void)loginRequestFailed:(ASIHTTPRequest *)request 
{ 
    NSError *error = [request error]; 

    //NSLog(@"login request failed with error: %@", [error localizedDescription]); 
    [self setLastError: error]; 

    if ([delegate respondsToSelector: @selector(gReaderLoginDidFail:)]) 
    { 
     [delegate gReaderLoginDidFail: self]; 
    } 

} 

登錄後,您可以使用sid和auth僞造請求到Reader的API端點。

例子:

- (ASIHTTPRequest *) requestForAPIEndpoint: (NSString *) apiEndpoint 
{ 
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: apiEndpoint]]; 
    [request addRequestHeader: @"User-Agent" value: @"NetNewsWire/3.2b25 (Mac OS X; http://www.newsgator.com/Individuals/NetNewsWire/)"]; 
    [request addRequestHeader: @"Cookie" value: [self sidHeader]]; 
    [request addRequestHeader: @"Authorization" value: [self authHeader]]; 

    return request; 
} 

關於谷歌閱讀器和它的私有API一個有趣的閱讀是http://timbroder.com/2007/08/google-reader-api-functions.html

請務必閱讀最新的評論:)

/編輯:我更新的代碼使用auth頭文件(谷歌今年6月推出的)。如果您使用OAuth,我想這將是放置您的OAuth令牌的地方。 guess

+0

感謝您的雅羅斯瓦夫!我很擔心爲應用程序使用非官方API。我可以做? – daidai 2010-09-23 00:05:02

+0

是和否:)不,因爲Apple不關心你是否使用別人的非官方API(他們只關心他們自己的API)。因此,如果您嘗試將Google閱讀器應用添加到商店中,您不會從Apple中受到任何麻煩。\ n \ n但是,非官方API總體上存在問題,因爲它們可以隨時更改。例如:我在這裏首先發布的示例代碼已損壞,我不得不修復它,因爲Google決定使用新的「Auth」參數進行身份驗證並忽略SID。支持非官方的第三方API始終是可行的,你應該意識到這一點。 – jsz 2010-09-23 10:40:24

+0

嗯,你真是一種痛苦。但是你認爲像Reedera這樣的應用程序都有同樣的問題?我不介意是否所有其他的Reader應用程序在同一時間失敗:) – daidai 2010-09-23 23:18:31