Google Reader API を利用したアプリを作りたいです。しかし、そのための公式 API がないことがわかりました。App Store のガイドライン/承認に関して、非公式 API の使用に問題はありますか? 他のアプリ (Reeder など) はこれを使用しますか?
また、ログインするための最良の方法は何ですか? 推奨される方法は OAuth ですか? Janrain を使用することは良い考えですか?
Google Reader API を利用したアプリを作りたいです。しかし、そのための公式 API がないことがわかりました。App Store のガイドライン/承認に関して、非公式 API の使用に問題はありますか? 他のアプリ (Reeder など) はこれを使用しますか?
また、ログインするための最良の方法は何ですか? 推奨される方法は OAuth ですか? Janrain を使用することは良い考えですか?
率直に言って、Apple は、Google の非公式 API を使用するかどうかは気にしません。
私は、同期に Google リーダーを使用する RSS リーダー アプリの顧客のために働いていました。OAuth は使用しませんでしたが、さまざまなリーダー URL への連続した呼び出しで使用するトークンを抽出する必要がある Cookie を返す標準の HTTP ログインを使用しました。
私の(古い)概念実証アプリからのログインコードを投稿できます。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 リーダーとそのプライベート API に関する興味深い記事はhttp://timbroder.com/2007/08/google-reader-api-functions.htmlです。
最新のコメントを必ずお読みください:)
/edit: auth ヘッダー (Google が今年 6 月に導入したもの) を使用するようにコードを更新しました。OAuth を使用する場合は、これが OAuth トークンを配置する場所になると思います。推測してみて
「Google Data API 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";
ここで、Design はフォルダ名です。このhttp://code.google.com/p/pyrfeed/wiki/GoogleReaderAPIを確認すると、非常に役立ちます。
アップデート
それ以来、この手法が最良/軽量/複雑でないことがわかりました: ネイティブ Google リーダー iPhone アプリケーション