如何加速Cloudkit的“fetchRecordWithID”

时间:2017-07-27 01:02:32

标签: objective-c cloudkit

第一次打开时我的应用程序执行的第一个操作是检查cloudkit是否有任何信息连接到用户iCloud帐户,因为如果有,则将信息下载到应用程序。我的问题是下载信息的方法在通过wifi连接时收集信息大约需要13秒,在使用移动数据时需要超过45秒。我一直在寻找优化,并发现在使用development数据库进行模拟时,使用produciton数据库进行模拟的结果更快,因此我可能会以错误的方式收集数据,因为有很多生产过程中产生的更多数据。

搜索信息的方法如下所示

CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName: userKey];

[_publicDatabase fetchRecordWithID:recordID completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
        if (error) {
            NSLog(@"Error in fethcing from user db %@", error);
            completion(error);
        } else {

            NSLog(@"User found in db");
            NSString *name = record[@"Name"];
            CKAsset *file = record[@"Image"];
            NSString *url = file.fileURL.absoluteString;
            NSMutableArray<NSString*> *codes = record[@"Groups"];

            NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString * basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
            NSData * binaryImageData = [NSData dataWithContentsOfURL:[file fileURL]];
            [binaryImageData writeToFile:[basePath stringByAppendingPathComponent:@"profilePicture.png"] atomically:YES];

            completion(nil);
        }

    }];

云端的信息基本上是名称,个人资料图片和群组代码。

有一种方法可以加速从云计算中获取此内容吗?因为通过移动数据获取这些数据不需要超过45秒是正常的事情,这没有任何意义。

1 个答案:

答案 0 :(得分:1)

您应该使用CKFetchRecordsOperation类而不是CKDatabase提供的获取功能。

原因是CKFetchRecordsOperation继承自Operation类,这允许更复杂和扩展的性能配置。

以下是您的代码修改以使用上面提到的类。

let fetchOperation: CKFetchRecordsOperation = CKFetchRecordsOperation(recordIDs: [ userKey ])
// Fetch only desired keys
fetchOperation.desiredKeys = [ "Name", "Image", "Groups" ]
// Performance tips
operation.qualityOfService = .userInitiated

fetchOperation.perRecordCompletionBlock = { (record: CKRecord?, recordID: CKRecordID?, error: Error) -> (Void) in
    guard let record = record else
    {
        print("There's no record in this fetch operations")

        if let error = error
        {
            print("err @ \(#function) -> \(error.localizedDescription)")
        }

        return
    }

    Dispatch.async.main 
    {
        // Save your image here...
    }
}

_publicDatabase.add(fetchOperation)

以下是一些提示......

  1. 仅获取您需要的字段。使用dediredKeys属性
  2. 设置操作的优先级。想一想它是后台操作,还是用户现在需要响应。更多信息,请访问qualityOfService财产
  3. 保存图像时,请在主要队列中进行,以及用户响应。
  4. PS:我现在注意到你的代码是Objective-C,我的例子是Swift,抱歉。