rishu1992
rishu1992

Reputation: 1434

youtube upload error: GTLJSONRPCErrorDomain Code=401

When I try to login to YouTube and upload a video, it gets uploaded without any issue. If I upload a video after 2-3 hours, I will get an error saying,

Error: Error Domain=com.google.GTLJSONRPCErrorDomain Code=401 "The operation couldn’t be completed. (Invalid Credentials)" UserInfo=0x14585d90 {error=Invalid Credentials, GTLStructuredError=GTLErrorObject 0x14d85ba0: {message:"Invalid Credentials" code:401 data:[1]}, NSLocalizedFailureReason=(Invalid Credentials)}

Here is the code which does Youtube login,

GIDSignIn *googleSignIn = [GDSharedInstance googleSDKApplicationSharedInstance];
    googleSignIn.delegate = self;
    googleSignIn.scopes  = [NSArray arrayWithObject:@"https://www.googleapis.com/auth/youtube"];
    [googleSignIn signIn];

signin delegate

  - (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error
    { 
// Auth is converted to use it for uploading a video
     GTMOAuth2Authentication *youTubeAuth = [[GTMOAuth2Authentication alloc] init];

        youTubeAuth.clientID = kClientID;
        youTubeAuth.clientSecret = @"xxx";
        youTubeAuth.userEmail = googleUser.profile.email;
        youTubeAuth.userID = googleUser.userID;
        youTubeAuth.accessToken = googleUser.authentication.accessToken;
        youTubeAuth.refreshToken = googleUser.authentication.refreshToken;
        youTubeAuth.expirationDate = googleUser.authentication.accessTokenExpirationDate;
        self.youTubeService.authorizer = youTubeAuth;
    }

Upload code,

NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:[NSURL URLWithString:path] error:&error];
    if (fileHandle) {
        NSString *mimeType = [self MIMETypeForFilename:filename
                                       defaultMIMEType:@"video/mov"];
        GTLUploadParameters *uploadParameters =
        [GTLUploadParameters uploadParametersWithFileHandle:fileHandle
                                                   MIMEType:mimeType];
        uploadParameters.uploadLocationURL = locationURL;

        GTLQueryYouTube *query = [GTLQueryYouTube queryForVideosInsertWithObject:video
                                                                            part:@"snippet,status,recordingDetails"
                                                                uploadParameters:uploadParameters];
            GTLServiceYouTube *service = self.youTubeService;

            self.uploadFileTicket = [service executeQuery:query
                                    completionHandler:^(GTLServiceTicket *ticket,
                                                        GTLYouTubeVideo *uploadedVideo,
                                                        NSError *error)
                                     {
                                        // here I will get 401 error
                                    }];

     }

Upvotes: 0

Views: 207

Answers (2)

JAL
JAL

Reputation: 42459

The problem here is that your auth token is expiring. You will have to use your refresh token to get a new, valid auth token after your old token expires.

If you are using an older version of the Google Plus iOS SDK, You can use GTMOAuth2Authentication to force a refresh of the auth token with the authorizeRequest: method.

From GTMOAuth2Authentication.h

// The request argument may be nil to just force a refresh of the access token,
// if needed.

- (void)authorizeRequest:(NSMutableURLRequest *)request
       completionHandler:(void (^)(NSError *error))handler;

Implementation:

// In your sign in method
[[GPPSignIn sharedInstance] setKeychainName:@"googleAuth"];

// ...

// Retrieving auth and refreshing token
GTMOAuth2Authentication *auth;
auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:@"googleAuth"
                                                             clientID:@"kYourGoogleClientId"
                                                         clientSecret:@"kYourGoogleClientSecret"];

NSLog(@"old auth: %@", auth);

[auth authorizeRequest:nil completionHandler:^(NSError *error) {
    if (error) {
        // no auth data or refresh failed
        NSLog(@"Error: %@", error);
    } else {
        // Auth token refresh successful
        NSLog(@"new auth: %@", auth);
    }
}];

Upvotes: 0

Vizllx
Vizllx

Reputation: 9246

The only problem is with the GTLServiceYouTube. GIDSignIn seems to handle the refresh tokens, so that the user is always logged in after the first login. But the GTLOAuth2Authentication only works on the first login and is broken after one hour.

The token needs to be refreshed.

Use this piece of code :-

- (void)applicationWillEnterForeground:(UIApplication *)application {

 [[GIDSignIn sharedInstance] signInSilently]

}

Upvotes: 1

Related Questions