iosobjective-cpostgoogle-apigoogle-plus

Cannot insert moment - Google Plus API


I have an iOS Application which authenticates with the Google Plus API via OAuth 2.0. The issue I have is that I can't POST my moment even though I have followed the Google Documentation exactly. Here is my POST request:

NSString *gp_moment = [NSString stringWithFormat:@"https://www.googleapis.com/plus/v1/people/me/moments/vault?access_token=%@", token_gplus];
        NSString *urlString = gp_moment;

        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:urlString]];
        [request setHTTPMethod:@"POST"];

        // Set the header - Content-Type.
        NSDictionary *the_header = @{@"Content-type" : @"application/json",
                                     @"userId" : @"me",
                                     @"collection" : @"vault",
                                     @"requestvisibleactions" : @"http://schemas.google.com/AddActivity"};

        [request setAllHTTPHeaderFields:the_header];

        // Set the metadata for the GP Moment (eg: name). -  request_visible_actions

        NSDictionary *metadata = @{@"target" : @{
                                           @"id" : @"replacewithuniqueidforaddtarget",
                                           @"image" : @"http://www.google.com/s2/static/images/GoogleyEyes.png",
                                           @"type": @"http://schema.org/CreativeWork",
                                           @"description" : @"test_desc",
                                           @"name" : @"TESTNAME",
                                           },
                                   @"type" : @"http://schemas.google.com/AddActivity"};

        // Convert metadata into JSON format and submit.
        NSError *jError = nil;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:metadata options:NSJSONWritingPrettyPrinted error:&jError];
        [request setHTTPBody:jsonData];

        NSHTTPURLResponse *response = nil;
        NSError *error = nil;

        NSData *returnedData;
        returnedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
        NSDictionary *headers = [response allHeaderFields];

        NSLog(@"DATA: %@", [[NSString alloc] initWithData:returnedData encoding:NSASCIIStringEncoding]);
        NSLog(@"%@", headers);
        NSLog(@"%@", response);
        NSLog(@"%@", error);

UPDATE - HOW I AM GETTING THE OAUTH TOKEN

I am getting the token by using the GTMOAuth2 iOS library provided by Google. It has 4 main classes which I am using:

The GTMOAuth2 Library files

This is the code I have implemented from the classes into my ViewController:

-(GTMOAuth2Authentication *)begin_authorization {

// Set the token URL to the token endpoint.
NSURL *tokenURL;

// Set a bogus redirect URI. It won't actually be used as the redirect will
// be intercepted by the OAuth library and handled in the app.
NSString *redirectURI;

GTMOAuth2Authentication *auth;
tokenURL = [NSURL URLWithString:@"https://accounts.google.com/o/oauth2/token"];
redirectURI = @"http://localhost:3000/oauth/callback/";

    auth = [GTMOAuth2Authentication authenticationWithServiceProvider:@"GooglePlus" tokenURL:tokenURL redirectURI:redirectURI clientID:kMyClientID_gplus clientSecret:kMyClientSecret_gplus];
[auth setScope:@"https://www.googleapis.com/auth/plus.login"];

// Set the appropriate token type.
[auth setTokenType:@"Bearer"];

return auth;
}

-(void)authorize:(NSString *)service {
    GTMOAuth2Authentication *auth = [self begin_authorization];

// Prepare the Authorization URL. We will pass in the name of the service
// that we wish to authorize with.
NSURL *authURL;
authURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://accounts.google.com/o/oauth2/auth/"]];

NSString *keyname;
keyname = [NSString stringWithFormat:@"GooglePlus"];

// Display the authentication view
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithAuthentication:auth authorizationURL:authURL keychainItemName:keyname delegate:self finishedSelector:@selector(viewController:finishedWithAuth:error:)];

[viewController setBrowserCookiesURL:[NSURL URLWithString:@"https://accounts.google.com/o/oauth2/auth/"]];

// Push the authentication view to our navigation controller instance
[[self navigationController] pushViewController:viewController animated:YES];
}

-(void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error {

if (error != nil) {
    // Authentication failed
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Authorization Failed" message:[error localizedDescription] delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
    [alertView show];
}

else {
    // Authentication succeeded
    // Assign the access token to the instance property for later use

    account_check = auth.accessToken;
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:account_check forKey:@"gp_token"];
    [defaults synchronize];
}
}

In the GTMOAuth2SignIn.m file I am also setting the offline_access and "requestvisisbleactions" parameters like so:

NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                 @"code", @"response_type",
                                 clientID, @"client_id",
                                 scope, @"scope", // scope may be nil
                                 @"force", @"approval_prompt",
                                 @"offline", @"access_type",
                                 @"http://schemas.google.com/AddActivity", @"requestvisibleactions",
                                 nil];

UPDATE - 2

I have tried looking through all the Google Plus documentation as well as looking through the differences between "requestvisisbleactions" and "request_visisble_actions" and still nothing works. Does anyone know what is wrong?

UPDATE - 3 - The error I am still getting

I keep on getting this error from Google Plus API. I just don't know why...:

{
"error": {
  "errors": [
   {
    "domain": "global",
    "reason": "unauthorized",
    "message": "Unauthorized"
   }
  ],
  "code": 401,
  "message": "Unauthorized"
 }
}

Solution

  • I believe that you need to use request_visible_actions. So your parameters might be set as

    NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       @"code", @"response_type",
                                       clientID, @"client_id",
                                       scope, @"scope", // scope may be nil
                                       @"force", @"approval_prompt",
                                       @"offline", @"access_type",
                                       @"http://schemas.google.com/AddActivity", @"request_visible_actions",
                                       nil];