Reputation: 1434
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
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
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