[英]Cloudkit Fetch very slow
Running the below code to fetch data from Cloudkit, at the moment it is taking a long to populate a tableView, depending on how many results there are, but if there are over 15 results it takes 10 seconds plus. 运行以下代码从Cloudkit中获取数据,目前,填充tableView花费的时间很长,具体取决于结果的数量,但是如果结果超过15个,则需要10秒钟以上的时间。 Are they any ways I can speed this up? 他们有什么办法可以加快速度吗?
This is my fetch func: 这是我的提取函数:
func loadData() {
venues = [CKRecord]()
let location = locationManager.location
let radius = CLLocationDistance(500)
let sort = CKLocationSortDescriptor(key: "Location", relativeLocation: location!)
let predicate = NSPredicate(format: "distanceToLocation:fromLocation:(%K,%@) < %f", "Location", location!, radius)
let publicData = CKContainer.defaultContainer().publicCloudDatabase
let query = CKQuery(recordType: "Venues", predicate: predicate )
query.sortDescriptors = [sort]
publicData.performQuery(query, inZoneWithID: nil) { (results:[CKRecord]?, error:NSError?) in
if let venues = results {
self.venues = venues
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
self.refreshControl.endRefreshing()
self.tableView.hidden = false
})
}
}
}
This is my tableView func: 这是我的tableView函数:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! NearMe2ViewCell
if venues.count == 0 {
return cell
}
let venue = venues[indexPath.row]
print(indexPath.row)
let venueLocation = venue["Location"] as? CLLocation
let venueTitle = (venue["Name"] as! String)
let venueImages = venue["VenuePhoto"] as! CKAsset
let userLocation = locationManager.location
let distanceBetween: CLLocationDistance = (venueLocation!.distanceFromLocation(userLocation!))
self.venueDistance = String(format: "%.f", distanceBetween)
cell.venueDistance?.text = venueDistance
cell.venueName.text = venueTitle
cell.venueImage?.image = UIImage(contentsOfFile: venueImages.fileURL.path!)
return cell
}
You should search for the record keys first, so a fetchOperation would include this directive. 您应该首先搜索记录键,因此fetchOperation将包含此指令。
fetchOperation.desiredKeys = ["record.recordID.recordName"]
That should be faster. 那应该更快。 Break your returned keys into the size you can display on the screen and go get them only. 将返回的键拆分为可以在屏幕上显示的大小,然后仅获取它们。 After you display them, go get the next batch in background thread, when you got that the next batch on background etc etc etc. 显示它们后,在后台线程中获取下一批,在后台等时获得下一批,等等。
Should add perhaps, that fetching the asset should be done on a separate thread too if possible, updating the table as you pull in the assets by reloading the table repeatedly. 应该补充一点,如果可能的话,资产的获取也应该在单独的线程上完成,在您通过重复加载表来获取资产时更新表。
Here is method to search and return keys. 这是搜索和返回键的方法。
func zap(theUUID:String) {
var recordID2Zap: String!
let predicate = NSPredicate(format: "(theUUID = %@)",theUUID)
let query = CKQuery(recordType: "Blah", predicate: predicate)
let searchOperation = CKQueryOperation(query: query)
searchOperation.desiredKeys = ["record.recordID.recordName"]
searchOperation.recordFetchedBlock = { (record) in
recordID2Zap = record.recordID.recordName
}
if error != nil {
print("ting, busted",error!.localizedDescription)
} else {
print("ok zapping")
if recordID2Zap != nil {
self.privateDB.delete(withRecordID: CKRecordID(recordName: recordID2Zap), completionHandler: {recordID, error in
NSLog("OK or \(error)")
})
}
}
}
searchOperation.qualityOfService = .background
privateDB.add(searchOperation)
theApp.isNetworkActivityIndicatorVisible = true
}
}
As for your tableview, and images... use the completion in your icloud code to send a notification to the table view. 至于您的表格视图和图像...在icloud代码中使用补全将通知发送到表格视图。
database.fetchRecordWithID(CKRecordID(recordName: recordId), completionHandler: {record, error in
let directDict = ["blah": "whatever"] as [String : String]
NotificationCenter.default.post(name: Notification.Name("blahDownloaded"), object: nil, userInfo: directDict)
}
And in the VC you register said notification. 然后在VC中注册上述通知。
NotificationCenter.default.addObserver(self, selector: #selector(blahDownloaded), name: Notification.Name("blahDownloaded"), object: nil)
func blahDownloaded(notification: NSNotification) {
if let userInfo = notification.userInfo as NSDictionary? as? [String: Any] {
//update you cell
//reload your table
}
Does that all make sense? 这一切有意义吗?
Your operation's qualityOfService
is defaulting to .utility
. 你操作的qualityOfService
被默认为.utility
。
There is an important note in the documentation for CKOperation
that states: CKOperation
文档中有一个重要说明,指出:
CKOperation objects have a default quality of service level of NSQualityOfServiceUtility (see qualityOfService). CKOperation对象的默认服务质量级别为NSQualityOfServiceUtility(请参阅qualityOfService)。 Operations at this level are considered discretionary, and are scheduled by the system for an optimal time based on battery level and other factors. 此级别的操作被认为是可任意选择的,并且由系统根据电池电量和其他因素在最佳时间安排。
Because CKOperation
inherits from NSOperation
you can configure the qualityOfService
property when your user is waiting on a request to finish. 由于CKOperation
从继承NSOperation
可以配置qualityOfService
当你的用户正在等待完成一个请求属性。 Here is some example code based off of yours above: 这是基于上述代码的一些示例代码:
let queryOperation = CKQueryOperation(query: query)
queryOperation.recordFetchedBlock = ...
queryOperation.queryCompletionBlock = ...
queryOperation.qualityOfService = .userInteractive
publicData.add(queryOperation)
Notice that this example explicitly creates a CKQueryOperation
instead of using the convenience API because it then gives you the flexibility to fully configure your operations before you enqueue them to be sent to the server. 请注意,此示例显式创建了CKQueryOperation
而不是使用便捷API,因为它使您可以灵活地在将操作排队发送到服务器之前完全配置您的操作。
In this case you can set the qualityOfService
to .userInteractive
because your user is actively waiting on the request to finish before they can use your app any further. 在这种情况下,您可以设置qualityOfService
到.userInteractive
因为你的用户正在积极等待的请求的完成它们可以在任何进一步的使用你的应用程序之前。 Learn more about the possible values at https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html 在https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html上了解有关可能值的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.