上传 Google Cloud Storage iOS

人气:778 发布:2022-10-16 标签: ios upload objective-c google-cloud-storage

问题描述

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

I'm trying to upload image to Google Cloud Storage for a couple days. I tried to use Google APIs Client Library for Objective-C from this link https://code.google.com/p/google-api-objectivec-client/wiki/Introduction.

这是我的代码实现:

_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,以便互联网上的所有用户都可以写入/上传到其中.

With that code, the error always appear "The operation couldn't be completed. (Access Not Configured. Please use Google Developers Console to activate the API for your project)". I don't know why error shows up whereas I've enabled all services related to storage like Google Cloud Storage and Google Cloud Storage JSON API and change ACL of the bucket so that all user on the internet can write/upload into it.

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

I also tried authentication process before upload. The code on 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];
});

当用户按下上传按钮时:

When user press upload button:

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;
};

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

With that implementation I got different error, "The operation couldn't be completed. (Insufficient Permission)".

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

What should I do so that I can upload image successfully? Any help will be appreciated.

非常感谢.

推荐答案

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

Finally I found the answer. Here is the code for authentication:

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 应用程序的密钥

Or if you want to upload without authentication, you have to assign API Key with Key for server applications not Key for iOS applications

_serviceStorage.APIKey = KEY_SERVER_APPLICATION;

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

I don't know why the uploading process successful when using Key for server applications whereas this is an iOS Application

676