8

在某些方面,我猜你可能会说我正在创建类似于 iOS 应用程序“Vine”的东西。一个社交网络,允许用户上传视频供其他人观看。我的整个项目已经准备就绪,我正在使用一个名为Parse的数据库服务,但是那里没有多少存储空间,如果你想扩大它,它会变得很昂贵。我想我可以使用我已经拥有的数据库,并且让“视频”的 sql 表有一个链接到实际视频文件的 URL 列。我一直在寻找数据存储服务,并找到了谷歌的“云存储”。

如果可能的话,我真正在寻找的是这样的用例:

  1. 客户端应用程序已准备好上传视频。
  2. 上传视频文件到some-cloud-service.com/myCompany/videoNameID.mp4
  3. 将此 URL 存储在数据库中“视频对象”的 URL 字段中。
  4. 当其他用户获取视频列表时,他们会获得一组名称和 URL
  5. 当用户想要播放某个视频时,从表中的 URL 中获取它。

我一直在想我可以使用云存储作为我的应用程序上传和访问文件的地方。我一直在查看 Google Cloud Storage 的 API 和文档,但是里面有很多我没有用的东西,而且我不明白其中的大部分内容。我开始认为“云存储”不是我想的那样。我只需要一个地方来直接从 iOS 应用程序(以及以后的网站)上传可能大量的大文件。Parse 提供的数据存储服务非常完美,但规模非常有限。我知道它有可能变得昂贵。从阅读这个价格谷歌服务,它看起来既便宜又正是我需要的,但我不明白,如果可能的话,我应该如何使用它来使用我的“凭据”直接上传文件,并接收一个 URL 作为文件结束位置的回报向上。

我可以为此使用 Google 的云存储吗?或者是其他东西?还是我完全误解了如何使用云存储?

4

3 回答 3

8

实际上,Google 服务的 Objective-C 包装库在这里有非常详细的文档: https ://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Preparing_to_Use_the_Library

它告诉您这个包装库是基于底层 JSON API 自动生成的。所以所有 GTLStorage... 类都将模仿 Google Storage 的 JSON API。执行实际 API 调用的类是 GTLQueryStorage。

如果您查看该 JSON 文档,您会发现有一个类 Objects 用于将数据存储到存储桶中: https ://developers.google.com/storage/docs/json_api/v1/#Objects上传新对象是“插入”

回到 GTLQueryStorage.h 文件,您将找到相应的 Objective-C 方法将新对象插入您的存储桶:

// Method: storage.objects.insert
// Stores new data blobs and associated metadata.
//  Required:
//   bucket: Name of the bucket in which to store the new object. Overrides the
//     provided object metadata's bucket value, if any.
//  Optional:
//   ifGenerationMatch: Makes the operation conditional on whether the object's
//     current generation matches the given value.
//   ifGenerationNotMatch: Makes the operation conditional on whether the
//     object's current generation does not match the given value.
//   ifMetagenerationMatch: Makes the operation conditional on whether the
//     object's current metageneration matches the given value.
//   ifMetagenerationNotMatch: Makes the operation conditional on whether the 
//     object's current metageneration does not match the given value.
//   name: Name of the object. Required when the object metadata is not
//     otherwise provided. Overrides the object metadata's name value, if any.
//   projection: Set of properties to return. Defaults to noAcl, unless the
//     object resource specifies the acl property, when it defaults to full.
//      kGTLStorageProjectionFull: Include all properties.
//      kGTLStorageProjectionNoAcl: Omit the acl property.
//  Upload Parameters:
//   Accepted MIME type(s): */*
//  Authorization scope(s):
//   kGTLAuthScopeStorageDevstorageFullControl
//   kGTLAuthScopeStorageDevstorageReadWrite
// Fetches a GTLStorageObject.
+ (id)queryForObjectsInsertWithObject:(GTLStorageObject *)object
                           bucket:(NSString *)bucket
                 uploadParameters:(GTLUploadParameters *)uploadParametersOrNil;

所以你应该:

  • 分配一个 GTLServiceStorage 实例
  • 将您的 API 密钥设置为该对象
  • 使用上面的类方法为您要使用正确存储桶保存的对象实例化一个 GTLQueryStorage 对象
  • 创建一个执行查询并获取完成处理程序以处理完成(成功、错误情况)的服务票证。
于 2013-08-19T12:08:38.227 回答
1

迟到的回应,但这可能会帮助其他人解决这个问题。此代码将视频上传到 GCS(经过测试和工作)

先认证

这将弹出 Google 身份验证视图控制器(您必须将“GTMOAuth2ViewTouch.xib”文件添加到您的项目中)。

- (void) uploadVideoToGoogleCloud {

// declare this
//@property (strong, nonatomic) GTLServiceStorage* serviceStorage;
//@property (strong, nonatomic) NSString* accessToken;

_serviceStorage = [[GTLServiceStorage alloc] init];
_serviceStorage = [GTLServiceStorage new];
_serviceStorage.additionalHTTPHeaders = @{@"x-goog-project-id": @"yourGoogleProjectId"};

// authenticate
GTMOAuth2ViewControllerTouch *oAuthVC =
[[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeStorageDevstorageReadWrite
                                           clientID:@"yourClientId from Client ID for iOS application"
                                       clientSecret:@"yourSecret from Client ID for iOS application"
                                   keychainItemName:@"use nil or give a name to save in keychain"
                                  completionHandler:^(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error) {

                                      _accessToken = [NSString stringWithFormat:@"Bearer %@", [auth.parameters objectForKey:@"access_token"]];

                                      _serviceStorage.additionalHTTPHeaders = @{@"x-goog-project-id": kProjectID, @"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];
                                      });
                                  }];


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

认证后上传视频

用户认证成功后,调用此函数上传视频

// upload video file
NSString *filename = @"yourVideoFileNameNoExtension";
NSString *pathToMovie = [[NSBundle mainBundle] pathForResource:filename ofType:@".mp4"];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:pathToMovie];
if (fileHandle) {

    GTLUploadParameters *uploadParam =
    [GTLUploadParameters uploadParametersWithFileHandle:fileHandle MIMEType:@"video/mp4"];

    GTLStorageObject *storageObj = [GTLStorageObject object];
    storageObj.name = @"thisWillAppearOnTheBucketAsTheFilename";

    GTLQueryStorage *query = [GTLQueryStorage queryForObjectsInsertWithObject:storageObj bucket:@"your-bucket-name" uploadParameters:uploadParam];

    GTLServiceTicket *ticket = [_serviceStorage executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
        NSLog(@"error:%@", error ? [error description] : @"query succeeded!");
    }];


    ticket.uploadProgressBlock = ^(GTLServiceTicket *ticket,
                                   unsigned long long numberOfBytesRead,
                                   unsigned long long dataLength) {
        NSLog(@"ticket: %@", ticket);
        NSLog(@"read %llu from %llu bytes", numberOfBytesRead, dataLength);
    };

} else {
    NSLog(@"no video file handle!");
}

希望这可以帮助 :)

于 2014-04-10T09:59:07.957 回答
0

是的,云存储是用于文件上传的。Parse 使用的术语比 Google 使用的更简单。对于 Google,您想阅读此文档,特别是“使用 XML API 实现可恢复上传”,但请阅读全文。

于 2013-08-17T22:19:20.703 回答