Using Google Reader API and OAuth in iPhone app

前端 未结 2 1700
梦谈多话
梦谈多话 2021-02-06 18:53

I want to make an app that uses on the Google Reader API. But I\'m finding out that there isn\'t an offical API for it - is there a problem using the unofficial API, in terms of

相关标签:
2条回答
  • 2021-02-06 19:08

    Ive since found this: "The Google Data APIs Objective-C Client Library provides an iPhone static library, a Mac OS X framework, and source code that make it easy to access data through Google Data APIs. " code.google.com/p/gdata-objectivec-client - which is great! It doesn't include the Reader API however (because it's not been released).

    I have been able to access the API by changing (in the OAuthSampleTouch example)

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

    in OAuthSampleRootViewControllerTouch.m to

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

    and

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

    to

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

    where Design is a folder name - check this http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI its a great help.


    Update

    I have since found that this technique to be the best / lightest / less-complicated : Native Google Reader iPhone Application

    0 讨论(0)
  • 2021-02-06 19:23

    Frankly Apple doesn't care if you use Google's unofficial API.

    I worked for a customer on a RSS reader app that used Google Reader for syncing. We didn't use OAuth but the standard HTTP login which returns you a cookie where you'll have to extract a token from to use in consecutive calls to the various reader URLs.

    I can post you the login code from my (old) proof of concept app. It uses ASIHTTP and some custom string categories. The idea is to send a login request, get the response and extract the session ID/auth code from the response's cookie header. Then you can use that session ID/auth code for consecutive calls.

    #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];
        }
    
    }
    

    After login you can use sid and auth to forge requests to the Reader's API endpoints.

    Example:

    - (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;
    }
    

    An interesting read about Google Reader and its private API is http://timbroder.com/2007/08/google-reader-api-functions.html

    Please make sure to read the latest comments :)

    /edit: I updated the code to use the auth header (which google introduced in june this year). I guess this would be the place to put your OAuth token in if you would use OAuth. guess

    0 讨论(0)
提交回复
热议问题