问题
In the app i am making, there will be a lot of data for the app to load from iCloud. My problem is that it does not load the data into a collection view until its finished receiving all the data(which takes a while). I want the app to load the data onto the collection view as its receiving the data, so the user does not have to wait. Or is it better to have the app only load some of the data at a time? How do i do this? Here is my code that i am using to load the data.
Note: I am using swift for this project.
func loadInfo() {
let predicate:NSPredicate = NSPredicate(value: true)
let query:CKQuery = CKQuery(recordType: "Data", predicate: predicate)
query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
if let database = self.publicDatabase {
database.performQuery(query, inZoneWithID: nil, completionHandler: { (records:[AnyObject]!, error:NSError!) in
if error != nil {
self.alert("Error: \(error.localizedDescription)", Message: "Make sure iCloud is turned on and you are connected to the internet")
}
else {
dispatch_async(dispatch_get_main_queue()) {
self.array.removeAll(keepCapacity: false)
for record in records {
let usernameRecord:CKRecord = record as CKRecord
self.array.append(usernameRecord.objectForKey("Info") as String)
}
//update data
self.collectionView.reloadData()
}
}
})
}}
回答1:
if you do a performQuery, the records will be returned all at once. If you want progress, then you can use the CKQueryOperation
. You will then get a call for each record for the block:
operation.recordFetchedBlock = { record in
When the query is ready, then there will be a call to.
operation.queryCompletionBlock = { cursor, error in
The number of records returned will be limited to a maximum (usually 100). That value can be set by using:
operation.resultsLimit = CKQueryOperationMaximumResults;
Just set it to the value you want.
Here is a sample that is based on the link from the comment below:
func loadInfo() {
let p = NSPredicate(value: true)
let q = CKQuery(recordType: "Data", predicate: p)
q.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let queryOperation = CKQueryOperation(query: q)
let database = self.publicDatabase
self.array.removeAll(keepCapacity: false)
queryOperation.recordFetchedBlock = fetchedARecord
queryOperation.queryCompletionBlock = { [weak self] (cursor : CKQueryCursor!, error : NSError!) in
if error != nil {
self.alert("Error: \(error.localizedDescription)", Message: "Make sure iCloud is turned on and you are connected to the internet")
}
else {
if cursor != nil {
println("there is more data to fetch")
let newOperation = CKQueryOperation(cursor: cursor)
newOperation.recordFetchedBlock = self!.fetchedARecord
newOperation.queryCompletionBlock = queryOperation.queryCompletionBlock
database.addOperation(newOperation)
}
} else {
dispatch_async(dispatch_get_main_queue()) {
self.collectionView.reloadData()
}
}
}
database.addOperation(queryOperation)
}
var i = 0
func fetchedARecord (record: CKRecord!) {
println("\(NSDate().timeIntervalSinceReferenceDate*1000) \(++i)")
self.array.append(record.objectForKey("Info") as String)
}
来源:https://stackoverflow.com/questions/29590925/how-do-i-make-my-cloudkit-app-load-the-data-as-its-loading