Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assertion failure in -[GTMHTTPUploadFetcher connectionDidFinishLoading:]

i am trying to upload a video on youtube using Google APIs Client Library for Objective-C, I using given below code but it is keep on giving me this error, i tried to run my account on youtube example project here again it gives that same error.

Can any one guide me where is the problem. I check YouTube Data API v3 is on in services page.

*** Assertion failure in -[GTMHTTPUploadFetcher connectionDidFinishLoading:], /Volumes/data/Work/test/DLNew/DL/google-api-objectivec-client-read-only/Source/HTTPFetcher/GTMHTTPUploadFetcher.m:399
2013-08-30 14:28:31.399 [1250:907] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unexpected response data (uploading to the wrong URL?)'

i check the code of GTMHTTPUploadFetcher class it is crashing the app on this link

`#if DEBUG
  // The initial response of the resumable upload protocol should have an
  // empty body
  //
  // This assert typically happens because the upload create/edit link URL was
  // not supplied with the request, and the server is thus expecting a non-
  // resumable request/response.
  NSAssert([[self downloadedData] length] == 0,
                    @"unexpected response data (uploading to the wrong URL?)");
 #endif

.

 NSString *path              = [[NSUserDefaults standardUserDefaults] objectForKey:@"MOVIEPATH"];
NSString *filename = [path lastPathComponent];
NSString *mimeType = [self MIMETypeForFilename:filename defaultMIMEType:@"video/mp4"];

NSError *eel=nil;

NSFileHandle *handle        = [NSFileHandle fileHandleForReadingFromURL:[NSURL URLWithString:path] error:&eel];
NSLog(@"error is  %@",eel);
if (!handle)
{
    NSLog(@"Failed to open file for reading");
    return;
}



GTLServiceYouTube *service      = [[GTLServiceYouTube alloc] init];
service.authorizer              = self.gTMOAuth2Authentication;

GTLUploadParameters *params     = [GTLUploadParameters uploadParametersWithFileHandle:handle MIMEType:mimeType];

GTLYouTubeVideoSnippet *snippet = [GTLYouTubeVideoSnippet object];
snippet.title                   = @"Test title";
snippet.descriptionProperty     = @"Test description";
snippet.tags                    = [NSArray arrayWithObjects:@"TestOne", @"TestTwo" ,nil];
snippet.categoryId              = @"17";

GTLYouTubeVideoStatus *status   = [GTLYouTubeVideoStatus object];
status.privacyStatus            = @"private";

GTLYouTubeVideo *video2          = [GTLYouTubeVideo object];
video2.snippet                   = snippet;
video2.status                    = status;

GTLQueryYouTube *query          = [GTLQueryYouTube queryForVideosInsertWithObject:video2 part:@"snippet,status" uploadParameters:params];



// Perform the upload
GTLServiceTicket *ticket        = [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error)
{
    if (error)
    {
        NSLog(@"ERROR: %@", error);
        return;
    }

    NSLog(@"SUCCESS! %@; %@;", ticket, object);
}];

ticket.uploadProgressBlock = ^(GTLServiceTicket *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength)
{
    NSLog(@"%lld / %lld", numberOfBytesRead, dataLength);
};

----------

The problem was i was logging from a new gmail account so i need to login in youtube site and need to create a channel before i can upload video to youtube. So now i can upload videos after creating a youtube channel. but How can i handle this scenario for other users, any idea

like image 681
Iqbal Khan Avatar asked Aug 30 '13 09:08

Iqbal Khan


2 Answers

I encountered the same crash and find out a solution. It seems that the client gets this crash also if the underlying request is a bad request but no response information are explicitly provided (my authorizer is valid and passes the check with the method canAuthorize as Ryan_IRL pointed out).

After a look at the library I found out that setting the preprocessor macro STRIP_GTM_FETCH_LOGGING and enabling the logging for the HTTPFetcher somewhere in the code

#if STRIP_GTM_FETCH_LOGGING
[GTMHTTPFetcher setLoggingEnabled:YES];
#endif

the logs are stored in the GTMHTTPDebugLogs folder inside the Simulator (something similar to /Users/<username>/Library/Application Support/iPhone Simulator/6.1/Applications/65451CDB-27D6-4BE2-910C-7F22D6A01832/GTMHTTPDebugLogs). There you can find the complete log in HTML format (...).

enter image description here

Clicking on 'request/response log' the following log was shown in my case.

Response body: (201 bytes)
{
  "id" : "gtl_1",
  "error" : {
    "message" : "Bad Request",
    "code" : -32602,
    "data" : [
      {
        "domain" : "youtube.video",
        "reason" : "invalidTitle",
        "locationType" : "other",
        "location" : "body.snippet.title",
        "message" : "Bad Request"
      }
    ]
  }
}

the bad request was related to the title (of the video to be uploaded) that was containing some forbidden chars. Fixing the title solved the crash and the video was uploaded correctly. A status 200 in this case is of course... frustrating and clearly wrong.

I'm strongly disappointed also by GTM Library, and by the use of the NSAssert for such situation in the first place.

like image 145
albertodebortoli Avatar answered Oct 14 '22 10:10

albertodebortoli


I had the same problem as you (assertion failure in GTMHTTPUploadFetcher.m:399) while uploading a video to YouTube. I'm posting this in the hopes of saving someone else a few minutes of debugging.

It turned out my problem was old code that set GTLServiceYouTube's APIKey, in addition to using OAuth2. Doh.

GTLServiceYouTube *youtube = [[GTLServiceYouTube alloc] init];
youtube.APIKey = @"-my-simple-api-access-key-"; //<-- offending line
[...]
youtube.authorizer = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
                                                                 clientID:kYouTubeClientID
                                                             clientSecret:kYouTubeClientSecret];

The fix was simply to leave APIKey nil, using only the OAuth2 authorizer. (APIKey is for 'Simple API Access' only, evidently, any hint of both leads to problems).

Fwiw, the http request succeeded (200 OK), but the http response told a different story. To view the response I added these two lines to the implementation of GTMHTTPUploadFetcher.m (perhaps theres a better way):

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [...]
    NSString *dataStr = [[NSString alloc] initWithData:self.downloadedData encoding:NSUTF8StringEncoding];
    NSLog(@"Downloaded data:%@",dataStr);
    [...]
}

The JSON in dataStr:

{
    "error": {
        "code": 403,
        "message": "Access Not Configured",
        "data": [{
            "domain": "usageLimits",
            "reason": "accessNotConfigured",
            "message": "Access Not Configured"
        }]
    },
    "id": "gtl_1"
}
like image 37
Davidm Avatar answered Oct 14 '22 10:10

Davidm