运行以下代码从Cloudkit获取数据,目前需要花费很长时间来填充tableView,具体取决于有多少结果,但如果有超过15个结果则需要10秒钟。他们有什么方法可以加快速度吗?
这是我的获取功能:
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
})
}
}
}
这是我的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
}
答案 0 :(得分:2)
您应首先搜索记录键,因此fetchOperation将包含此指令。
fetchOperation.desiredKeys = ["record.recordID.recordName"]
那应该更快。将返回的密钥分解为可以在屏幕上显示的大小,然后只获取它们。显示它们之后,在后台线程中获取下一批,当你在背景等处获得下一批等时。
或许应该添加,如果可能的话,也应该在一个单独的线程上获取资产,在重复重新加载表时拉入资产时更新表。
这是搜索和返回键的方法。
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
}
}
至于你的tableview和图片......使用你的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)
}
在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
}
这一切都有意义吗?
答案 1 :(得分:2)
您的操作qualityOfService
默认为.utility
。
documentation for CKOperation
中有一条重要说明:
CKOperation对象具有NSQualityOfServiceUtility的默认服务质量等级(请参阅qualityOfService)。此级别的操作被视为自行决定,并由系统根据电池电量和其他因素安排最佳时间。
由于CKOperation
继承自NSOperation
,因此您可以在用户等待请求完成时配置qualityOfService
属性。以下是基于您的一些示例代码:
let queryOperation = CKQueryOperation(query: query)
queryOperation.recordFetchedBlock = ...
queryOperation.queryCompletionBlock = ...
queryOperation.qualityOfService = .userInteractive
publicData.add(queryOperation)
请注意,此示例显式创建CKQueryOperation
而不是使用便捷API,因为它可以让您在将操作排入队列之前完全配置操作。
在这种情况下,您可以将qualityOfService
设置为.userInteractive
,因为您的用户正在等待请求完成,然后才能再使用您的应用。详细了解https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html