断言失败 - [GTMHTTPUploadFetcher connectionDidFinishLoading:]

时间:2013-08-30 09:38:55

标签: iphone ios objective-c google-api-objc-client

我正在尝试使用针对Objective-C的Google API客户端库在youtube上传视频, 我使用下面给出的代码,但它继续给我这个错误,我试图在youtube示例项目上再次运行我的帐户,它给出了同样的错误。

任何人都可以指导我问题在哪里。我查看了服务页面中的YouTube Data API v3。

*** 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?)'

我检查GTMHTTPUploadFetcher类的代码,它正在崩溃此链接上的应用程序

`#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);
};

----------

问题是我从新的Gmail帐户登录,所以我需要在youtube网站登录,并且需要创建一个频道才能将视频上传到youtube。所以现在我可以在创建youtube频道后上传视频。但我如何为其他用户处理这种情况,任何想法

8 个答案:

答案 0 :(得分:6)

我遇到了同样的崩溃并找到了解决方案。 如果底层请求是一个错误的请求,但是没有明确提供响应信息,那么客户端似乎也会遇到此崩溃(我的授权者是有效的,并通过方法canAuthorize传递检查,如Ryan_IRL指出的那样)

看了一下库之后,我发现设置预处理器宏STRIP_GTM_FETCH_LOGGING并在代码中的某处启用HTTPFetcher的日志记录

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

日志存储在模拟器内的GTMHTTPDebugLogs文件夹中(类似于/Users/<username>/Library/Application Support/iPhone Simulator/6.1/Applications/65451CDB-27D6-4BE2-910C-7F22D6A01832/GTMHTTPDebugLogs)。在那里,您可以找到完整的HTML格式(...)。

enter image description here

点击“请求/响应日志”,我的案例中显示了以下日志。

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"
      }
    ]
  }
}

错误请求与包含一些禁止字符的标题(要上传的视频)有关。修复标题解决了崩溃并正确上传了视频。在这种情况下,状态200当然是......令人沮丧且明显错误。

我对GTM图书馆以及首先使用NSAssert这种情况感到非常失望。

答案 1 :(得分:1)

在将视频上传到YouTube时,我遇到了与您相同的问题(GTMHTTPUploadFetcher.m:399中的断言失败)。我发布这篇文章是为了节省其他人几分钟的调试时间。

原来我的问题是旧代码将添加中的GTLServiceYouTube的APIKey设置为使用OAuth2。卫生署。

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

修复只是将APIKey保留为零,仅使用OAuth2授权程序。 (APIKey仅用于'简单API访问',显然,任何两种提示都会导致问题)。

Fwiw,http请求成功(200 OK),但http响应讲述了另一个故事。为了查看响应,我将这两行添加到GTMHTTPUploadFetcher.m的实现中(也许是更好的方法):

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

dataStr中的JSON:

{
    "error": {
        "code": 403,
        "message": "Access Not Configured",
        "data": [{
            "domain": "usageLimits",
            "reason": "accessNotConfigured",
            "message": "Access Not Configured"
        }]
    },
    "id": "gtl_1"
}

答案 2 :(得分:0)

很抱歉,如果我在这里做出一个假设,但我遇到了和你一样的错误,事实证明这个问题实际上是我的授权人。确保您使用auth处理错误,并将auth应用于service.authorizer

if (![self.youTubeAuth canAuthorize]) {
    // ...
}
service.authorizer = auth;

由于GTMOAuth2ViewControllerTouch初始化程序的作用域不正确,我也遇到了这个问题。 @""会给你提供比错误范围更好的结果。查看YouTube示例应用。

答案 3 :(得分:0)

我想您需要从API服务标签

启用Drive API和Drive SDK

将项目的服务切换为开启,然后重试。

如果两者都打开,请确保在manifest中设置了“api_console_project_id”:“xxxxxxxxxxxxx”参数。

答案 4 :(得分:0)

我从这里找到了它,google-youtube-api-v3-ios-app-key-403-error-code

基本上,如果我们使用Key for browser apps代替Key for iOS apps,它就会有用。

答案 5 :(得分:0)

问题是我从新的Gmail帐户登录,因此我需要在youtube网站登录,并且需要创建频道才能将视频上传到youtube。所以现在我可以在创建youtube频道后上传视频。但我如何为其他用户处理这种情况,任何想法

答案 6 :(得分:0)

不知道是否有人已经为此找到了解决方案,但这是我实现的(在Swift中)以避免应用程序崩溃:

首先使用以下方法检查Youtube频道状态:

GTLQueryYouTube.queryForChannelsListWithPart部分设置为&#34;状态&#34;

如果&#34;的值已链接&#34;参数在响应中不为0,然后仅使用

上传视频

GTLQueryYouTube.queryForVideosInsertWithObject

否则请先要求用户关联youtube频道。

答案 7 :(得分:-2)

GTLServiceYouTube * youtube = [[GTLServiceYouTube alloc] init]; youtube.APIKey = @“ - my-simple-api-access-key-”; //&lt; - 违规行 youtube.authorizer = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName                                                                  clientID的:kYouTubeClientID                                                              clientSecret:kYouTubeClientSecret];