ios - 从 CloudKit 获取 CKAsset 图像非常慢

标签 ios swift cloudkit

我正在使用 CloudKit 作为我的 iOS 应用程序的服务器后端。我用它来存放一些相对静态的数据以及一些图像 (CKAsset)。当我真正从公共(public)数据库中获取这些 Assets 时,我遇到了一个问题。它们以极慢的速度加载。

我的用例是将图像加载到 Collection View 内的每个单元格中。这些图像只有 200kb 大小,但提取过程平均需要 2.2 秒才能完成下载并将图像设置在一个单元格中。为了比较,我获取了相似大小的图片的 URL,并使用 NSURLSession 加载它们。每张图片的加载时间仅为 0.18 - 0.25 秒。

我尝试了多种从CK下载图片的方式:直接抓取记录、查询、操作查询。他们都有相似的结果。在为单元格设置图像之前,我还在完成 block 内分派(dispatch)回主队列。

我的数据库设置为具有一个包含多个数据字段的主要对象。然后,我为照片设置了一个向后引用样式系统,其中每张照片都只引用了一个主要对象。这样我就可以按需加载照片,而不会影响主要数据。

看起来像这样:

主要对象: title: String, startDate: Date

照片对象: owner: String(对主要对象的引用),image: Asset

这是我尝试直接获取其中一张照片的示例请求:

let publicDb = CKContainer.defaultContainer().publicCloudDatabase
let configRecordId = CKRecordID(recordName: "e783f542-ec0f-46j4-9e99-b3e3ez505adf")

publicDb.fetchRecordWithID(configRecordId) { (record, error) -> Void in
    dispatch_async(dispatch_get_main_queue()) {
        guard let photoRecord = record else { return }
        guard let asset = photoRecord["image"] as? CKAsset else { return }

        guard let photo = NSData(contentsOfURL: asset.fileURL) else { return }

        let image = UIImage(data: photo)!

        cell.cardImageView.image = image
    }
}

我似乎不明白为什么这些图片下载要花这么长时间,但如果我不能让它们在合理的时间内加载,那真的很糟糕。

更新:我尝试使用较小的图像(23kb)进行提取操作。获取速度更快,从 0.3 到 1.1 秒不等。这样更好,但仍然不符合我对 CloudKit 应该能够提供的功能的期望。

最佳答案

我正在使用 CKQueryOperation。我发现一旦我将以下行添加到我的代码中,下载 CKAssets 的速度就会提高大约 5-10 倍。

    queryOperation.qualityOfService = .UserInteractive

这是我的完整代码:

func getReportPhotos(report:Report, completionHandler: (report:Report?, error:NSError?) -> ()) {
    let photo : Photo = report.photos![0] as! Photo
    let predicate : NSPredicate = NSPredicate(format: "recordID = %@", CKRecordID(recordName: photo.identifier!))
    let query : CKQuery = CKQuery(recordType: "Photo", predicate: predicate)
    let queryOperation : CKQueryOperation = CKQueryOperation()
    queryOperation.query = query
    queryOperation.resultsLimit = numberOfReportsPerQuery        
    queryOperation.qualityOfService = .UserInteractive
    queryOperation.recordFetchedBlock = { record in
        photo.date = record.objectForKey("date") as? NSDate
        photo.fileType = record.objectForKey("fileType") as? String
        let asset : CKAsset? = record.objectForKey("image") as? CKAsset
        if asset != nil {
            let photoData : NSData? = NSData(contentsOfURL:asset!.fileURL)
            let photo : Photo = report.photos![0] as! Photo
            photo.image = UIImage(data:photoData!)
        }

    }
    queryOperation.queryCompletionBlock = { queryCursor, error in
        dispatch_async(dispatch_get_main_queue(), {
            completionHandler(report: report, error: error)
        })
    }
    publicDatabase?.addOperation(queryOperation)
}

关于ios - 从 CloudKit 获取 CKAsset 图像非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35448287/

相关文章:

swift - NSWindow 宽度未使用 setFrame(frame, display, animate) 更新

ios - 如何在每个 View 上添加 UISearchbar

swift - 无法过滤对象数组

cloudkit - CKFetchDatabaseChangesOperation 不返回记录区域 ID

arrays - 需要在 CloudKit 查询后立即触发完成 block

ios - 来自 iOS 的 Twilio 拨出电话

ios - Google Plus iOS SDK 不刷新过期 token

iphone - 将 UIImage 转换为 CVImageBufferRef

ios - 通过在另一个 View 中更改设置来搜索 NSFetchedResults

ios - CloudKit:获取用户的名字/姓氏