我想制作一个在 Google Reader API 上使用的应用程序。但我发现它没有官方 API - 就 App Store 指南/批准而言,使用非官方 API 是否有问题?其他应用程序(Reeder 等)会使用这个吗?
另外登录的最佳方法是什么?OAuth 是首选方法吗?使用 Janrain 是个好主意吗?
我想制作一个在 Google Reader API 上使用的应用程序。但我发现它没有官方 API - 就 App Store 指南/批准而言,使用非官方 API 是否有问题?其他应用程序(Reeder 等)会使用这个吗?
另外登录的最佳方法是什么?OAuth 是首选方法吗?使用 Janrain 是个好主意吗?
坦率地说,Apple 不在乎你是否使用 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 = @"my.googlelogin@gmail.com";
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;
}
关于 Google Reader 及其私有 API 的有趣读物是http://timbroder.com/2007/08/google-reader-api-functions.html
请务必阅读最新评论:)
/edit:我更新了代码以使用 auth 标头(谷歌在今年 6 月推出)。如果您使用 OAuth,我想这将是放置您的 OAuth 令牌的地方。猜测
我后来发现:“Google Data APIs Objective-C Client Library 提供了一个 iPhone 静态库、一个 Mac OS X 框架和源代码,可以轻松通过 Google Data APIs 访问数据。” 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";
其中 Design 是一个文件夹名称 - 检查这个http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI它有很大的帮助。
更新
从那以后,我发现这种技术是最好的/最轻的/不太复杂的: Native Google Reader iPhone Application