Использование Google Reader API и OAuth в приложении для iPhone - PullRequest
2 голосов
/ 22 сентября 2010

Я хочу создать приложение, которое использует API Google Reader.Но я обнаружил, что для него не существует официального API - есть ли проблема с использованием неофициального API с точки зрения рекомендаций / одобрения App Store?Будут ли другие приложения (Reeder и т. Д.) Использовать это?

Кроме того, каков наилучший способ входа в систему?Является ли OAuth предпочтительным методом?Является ли использование Janrain хорошей идеей?

Ответы [ 2 ]

7 голосов
/ 22 сентября 2010

Честно говоря, Apple не волнует, используете ли вы неофициальный API Google.

Я работал на клиента в приложении для чтения RSS, которое использовало Google Reader для синхронизации. Мы не использовали OAuth, но стандартный HTTP-логин, который возвращает вам cookie, из которого вам нужно извлечь токен, чтобы использовать его при последовательных вызовах различных URL-адресов читателей.

Я могу опубликовать вам код входа из моего (старого) приложения для проверки концепции. Он использует ASIHTTP и некоторые пользовательские строковые категории. Идея состоит в том, чтобы отправить запрос на вход в систему, получить ответ и извлечь идентификатор сеанса / код авторизации из заголовка cookie ответа. Затем вы можете использовать этот идентификатор сеанса / код авторизации для последовательных вызовов.

#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 для подделки запросов к конечным точкам API Reader.

Пример:

- (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 (который Google ввел в июне этого года). Я думаю, это было бы место, где можно вставить свой токен OAuth, если вы используете OAuth. догадка

6 голосов
/ 03 ноября 2010

С тех пор я обнаружил: «Клиентская библиотека Objective-C API данных Google содержит статическую библиотеку iPhone, платформу Mac OS X и исходный код, облегчающие доступ к данным через API данных Google». .google.com / p / gdata -jectivec-client - это здорово! Однако он не включает в себя Reader API (поскольку он не был выпущен).

Мне удалось получить доступ к API, изменив (в примере OAuthSampleTouch)

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

в OAuthSampleRootViewControllerTouch.m to

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 Reader для iPhone

...