从CloudKit提取CKAsset图像非常慢 [英] Fetching CKAsset Image From CloudKit is Very Slow

查看:117
本文介绍了从CloudKit提取CKAsset图像非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将CloudKit用作iOS应用程序的服务器后端。我使用它来存储一些相对静态的数据以及少量图像(CKAsset)。当我需要从公共数据库中实际获取那些资产时,我遇到了一个问题。它们以极慢的速度加载。

I am using CloudKit as a server backend for my iOS application. I'm using it to house some relatively static data along with a handful of images(CKAsset). I ran into a problem when the time came for me to actually fetch those assets from the public database. They load at an excruciatingly slow speed.

我的用例是将图像加载到集合视图内的每个单元格中。图像的大小仅为200kb,但提取过程平均需要2.2秒才能完成下载并在单元格中设置图像。为了进行比较,我使用了类似大小的图片的URL,并使用NSURLSession加载了它们。加载每个图像仅花费0.18-0.25秒。

My use case is to load an image into every cell inside of a collection view. The images are only 200kb in size, but the fetch process took an average of 2.2 seconds for the download to complete and set the image in a cell. For comparison, I took URLs of similar sized stock images and loaded them in using NSURLSession. It took a mere 0.18 - 0.25 seconds for each image to load.

我尝试了多种从CK下载图像的方法:直接获取记录,查询和操作查询。他们都有相似的结果。在设置单元的图像之前,我还将分派回完成块内的主队列。

I have tried multiple different ways of downloading the images from CK: direct fetch of the record, query, and operation query. All of them have similar results. I am also dispatching back to the main queue within the completion block prior to setting the image for the cell.

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

My database is setup to have a primary object with several fields of data. I then setup a backwards reference style system for the photos, where each photo just has a reference to a primary object. That way I can load the photos on demand without bogging down the main data.

它看起来像这样:

主要对象:
标题:字符串,开始日期:日期

照片对象:
所有者:字符串(对主要对象的引用),图像:资产

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

Here is an example request that I tried to directly fetch one of the photos:

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

我似乎无法弄清楚为什么这些图像下载花了这么长时间,但是如果我不能在合理的时间内加载它们,那确实是最畅销的。

I can't seem to figure out why these image downloads are taking so long, but it's really quite the showstopper if I can't get them to load in a reasonable about of time.

更新:我尝试使用较小的图像23kb进行获取操作。提取速度更快,范围为0.3-1.1秒。更好,但是仍然不能满足我对CloudKit应该能够提供的期望。

推荐答案

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

I am using CKQueryOperation. I found that once I added the following line to my code that downloading CKAssets sped up by about a factor of 5-10x.

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

这篇关于从CloudKit提取CKAsset图像非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆