【问题标题】:Upload Google Cloud Storage iOS上传 Google Cloud Storage iOS
【发布时间】:2014-04-16 03:17:22
【问题描述】:

我正在尝试将图片上传到 Google Cloud Storage 几天。 我尝试通过此链接https://code.google.com/p/google-api-objectivec-client/wiki/Introduction 使用 Google APIs Client Library for Objective-C。

这是我的代码实现:

_serviceStorage = [GTLServiceStorage new];
_serviceStorage.APIKey = API_KEY;
_serviceStorage.additionalHTTPHeaders = @{@"x-goog-project-id": PROJECT_ID};

GTLUploadParameters *uploadParam = [GTLUploadParameters uploadParametersWithData:_imageData MIMEType:@"image/jpeg"];
GTLStorageObject *storageObj = [GTLStorageObject object];

GTLQueryStorage *query = [GTLQueryStorage queryForObjectsInsertWithObject:storageObj bucket:BUCKET_NAME uploadParameters:uploadParam];
GTLServiceTicket *ticket = [_serviceStorage executeQuery:query delegate:self didFinishSelector:@selector(serviceTicket:finishedWithObject:error:)];

ticket.uploadProgressBlock = ^(GTLServiceTicket *ticket,
                               unsigned long long numberOfBytesRead,
                               unsigned long long dataLength) {
    self.progressView.progress = (float)numberOfBytesRead/(float)dataLength;
};

使用该代码,错误总是出现“操作无法完成。(访问未配置。请使用 Google Developers Console 为您的项目激活 API)”。我不知道为什么会出现错误,而我已经启用了所有与存储相关的服务,例如 Google Cloud Storage 和 Google Cloud Storage JSON API,并更改了存储桶的 ACL,以便互联网上的所有用户都可以写入/上传到其中。

我还尝试了上传前的身份验证过程。 viewDidLoad 上的代码:

_serviceStorage = [GTLServiceStorage new];
_serviceStorage.additionalHTTPHeaders = @{@"x-goog-project-id": PROJECT_ID};
GTMOAuth2ViewControllerTouch *oAuthVC = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kScope
                                                                                   clientID:kClientID
                                                                               clientSecret:kClientSecret
                                                                           keychainItemName:kKeychainItemName
                                                                          completionHandler:^(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error) {
                                                                              dispatch_async(dispatch_get_main_queue(), ^{
                                                                                  [self dismissViewControllerAnimated:YES completion:nil];
                                                                              });
                                                                              auth.authorizationTokenKey = @"access_token";
                                                                              _serviceStorage.authorizer = auth;
                                                                          }];

dispatch_async(dispatch_get_main_queue(), ^{
    [self presentViewController:oAuthVC animated:YES completion:nil];
});

当用户按下上传按钮时:

GTLUploadParameters *uploadParam = [GTLUploadParameters uploadParametersWithData:_imageData MIMEType:@"image/jpeg"];
GTLStorageObject *storageObj = [GTLStorageObject object];

GTLQueryStorage *query = [GTLQueryStorage queryForObjectsInsertWithObject:storageObj bucket:BUCKET_NAME uploadParameters:uploadParam];
GTLServiceTicket *ticket = [_serviceStorage executeQuery:query delegate:self didFinishSelector:@selector(serviceTicket:finishedWithObject:error:)];

ticket.uploadProgressBlock = ^(GTLServiceTicket *ticket,
                               unsigned long long numberOfBytesRead,
                               unsigned long long dataLength) {
    self.progressView.progress = (float)numberOfBytesRead/(float)dataLength;
};

使用该实现我得到了不同的错误,“无法完成操作。(权限不足)”

我应该怎么做才能成功上传图片? 任何帮助将不胜感激。

非常感谢。

【问题讨论】:

    标签: ios objective-c upload google-cloud-storage


    【解决方案1】:

    我终于找到了答案。以下是验证代码:

    GTMOAuth2ViewControllerTouch *oAuthVC = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeStorageDevstorageReadWrite
                                                                                           clientID:kClientID
                                                                                       clientSecret:kClientSecret
                                                                                   keychainItemName:kKeychainItemName
                                                                                  completionHandler:^(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error) {
    
                                                                                      _accessToken = [NSString stringWithFormat:@"Bearer %@", [auth.parameters objectForKey:@"access_token"]];
    
                                                                                      _serviceStorage.additionalHTTPHeaders = @{@"x-goog-project-id": PROJECT_ID, @"Content-Type": @"application/json-rpc", @"Accept": @"application/json-rpc", @"Authorization": _accessToken};
    
                                                                                      _serviceStorage.authorizer = auth;
    
    
                                                                                      dispatch_async(dispatch_get_main_queue(), ^{
                                                                                          [self dismissViewControllerAnimated:YES completion:nil];
                                                                                      });
                                                                                  }];
    

    这里是上传过程:

    GTLUploadParameters *uploadParam = [GTLUploadParameters uploadParametersWithData:_imageData MIMEType:@"image/jpeg"];
    GTLStorageObject *storageObj = [GTLStorageObject object];
    storageObj.name = FILE_NAME;
    
    GTLQueryStorage *query = [GTLQueryStorage queryForObjectsInsertWithObject:storageObj bucket:BUCKET_NAME uploadParameters:uploadParam];
    GTLServiceTicket *ticket = [_serviceStorage executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
    }];
    
    ticket.uploadProgressBlock = ^(GTLServiceTicket *ticket,
                                   unsigned long long numberOfBytesRead,
                                   unsigned long long dataLength) {
        self.progressView.progress = (float)numberOfBytesRead/(float)dataLength;
    };
    

    或者,如果您想在没有身份验证的情况下上传,则必须使用 服务器应用程序的密钥而不是 iOS 应用程序的密钥

    分配 API 密钥
    _serviceStorage.APIKey = KEY_SERVER_APPLICATION;
    

    我不知道为什么使用 Key for server applications 上传过程会成功,而这是一个 iOS 应用程序

    【讨论】:

    • 如何在谷歌云存储 iOS 中验证服务帐户。我在 _serviceStorage 中给出了 KEY_SERVER_APPLICATION,但它显示“访问未配置 - 403 错误”
    • 我也面临同样的问题,你能提供我可以从哪里获取 iOS 代码库的链接吗? .上面给出的链接适用于 Mac os x。