我在我的应用中使用CloudKit作为一种远程持久化数据的方式。我的一条记录有一个保存图像的CKAsset属性。当我获取记录时,我意识到完成查询需要花费很多时间。经过多次测试,我得出结论,当您查询记录时,CloutKit会下载包含record对象的整个资产文件。因此,当您从record对象获取Asset并请求它为fileURL时,它会为您提供一个本地文件路径URL,而不是HTTP种类的URL。这对我来说是一个问题,因为在查询结束之前,您必须让用户等待很长时间才能下载整个记录(及其关联的图像)。在Parse的背景下,Parse用于提供HTTP URL,查询速度足够快,可以在异步加载图像的同时加载带有对象的UI。我的问题是,我如何才能实现Parse所做的事情?我需要限制查询下载资产数据,并获取异步加载图像的链接。
发布于 2016-05-29 18:44:59
您可以使用CloudKit JavaScript来访问资产的url。下面是一个例子;
(使用Alamofire和SwiftyJSON)
func testRecordRequest() -> Request {
let urlString = "https://api.apple-cloudkit.com/database/1/" + Constants.container + "/development/public/records/query?ckAPIToken=" + Constants.cloudKitAPIToken
let query = ["recordType": "TestRecord"]
return Alamofire.request(.POST, urlString, parameters: ["query": query], encoding: .JSON, headers: nil)
}JSON响应包含资产的"downloadURL“。
"downloadURL": "https://cvws.icloud-content.com/B/.../${f}?o=AmVtU...""${f}“似乎是一个变量,因此请将其更改为您喜欢的任何内容。
let downloadURLString = json["fields"][FieldNames.image]["value"]["downloadURL"].stringValue
let recordName = json["recordName"].stringValue
let fileName = recordName + ".jpg"
let imageURLString = downloadURLString.stringByReplacingOccurrencesOfString("${f}", withString: fileName)现在我们可以使用这个urlString来创建一个NSURL,并将其用于任何图像和缓存解决方案,如翠鸟,HanekeSwift等(您可能还想保存图像类型png/jpg)
发布于 2016-01-31 02:02:21
对同一记录进行两个单独的调用。第一个调用应该获取您想要的所有非资产字段,然后第二个请求应该获取所需的资产。
类似于:
let dataQueryOperation = CKQueryOperation(query: CKQuery(predicate: myPredicate)
dataQueryOperation.desiredKeys = ["name", "age"] // etc
database.addOperation(dataQueryOperation)
let imageQueryOperation = CKQueryOperation(query: CKQuery(predicate: myPredicate)
imageQueryOperation.desiredKeys = ["images"]
database.addOperation(imageQueryOperation)如果需要,可以将其重构为一个方法,以便您可以轻松地为每个包含资产的字段创建新的CKQueryOperation。
祝你打猎愉快。
发布于 2016-02-04 22:41:33
就像其他人所说的,你无法获得CKAsset的网址(网页)。所以你最好的选择是1.使用一个fetch操作,每一个UIImageView都有进度。我已经构建了一个向用户显示进度的自定义进程。不包含缓存,但您可以创建一个类并采用NSCoding,并将整个记录保存到缓存目录中。在这里您可以看到一个fetch,我已经完成了这个fetch,它将资产发送回我调用它的地方,以便将它与我的其他数据组合在一起。
// only get the asset in this fetch. we have everything elselet操作=CKFetchRecordsOperation(recordID: myRecordID)
operation.desiredKeys = ["GameTurnImage"]
operation.perRecordProgressBlock = {
record,progress in
dispatch_async(dispatch_get_main_queue(), {
self.progressIndicatorView.progress = CGFloat(progress)
})
}
operation.perRecordCompletionBlock = {
record,recordID,error in
if let _ = record{
let asset = record!.valueForKey("GameTurnImage") as? CKAsset
if let _ = asset{
let url = asset!.fileURL
let imageData = NSData(contentsOfFile: url.path!)!
dispatch_async(dispatch_get_main_queue(), {
self.image = UIImage(data: imageData)
self.progressIndicatorView.reveal()
})
completion(asset!)
}
}
}
CKContainer.defaultContainer().publicCloudDatabase.addOperation(operation)另一种选择是将图像存储在亚马逊网络服务服务器或类似的服务器上,然后您可以使用SDWebImage之类的东西来执行所有的缓存或繁重的操作,并将CKRecord中的字符串保存到图像中。
我曾询问过几个人关于CKAsset公开url的功能。我不知道CloudKit的JS,但可能有一种方法可以做到这一点,但我会让其他人对此发表评论。
https://stackoverflow.com/questions/35104247
复制相似问题