Recently added to the input method pocketed called "Logarithmic Cloud"s things,It is not difficult,Simpler than using iCloud Document,But not too much information online,You started by those tutorials to real life should not be a problem,But want to enhance the user experience,It is not so easy。Here we take a look at,How to get CloudKit run more fun。
CKDatabaseOperation
In General,You get a data might look like this:
1 2 3 4 |
let publicDatabase = CKContainer(identifier: "iCloud.com.xxx").publicCloudDatabase publicDatabase.fetch(withRecordID: recordId) { (record, _) in .... } |
The method is simple enough to use fetch,But it is a convenient option,It is very low, then the default priority execution,At this time you should know, Network Communications CloudKit not by your program decision,But by ios handled,so,SuchLow priority,It will lead to very slow speed of your data acquisition,If it is slightly larger (eg 1M-size image) data,Then you might wait to Daisy thought your program crashed。
Now you finally know what makes you so slow CloudKit。This really is not iCloud pot。
so,This time using the manual setting of priorities compulsory acquisition is a good choice - of course,Taking into account the majority of cases we are not in the background but need to slowly get immediately presented to the user, right?
Then you can consider using CKDatabaseOperation Subclass,It allows you to create a series of tasks,Such as uploading、Download、Delete, etc.,Continue the previous example,Here we get a record (or multiple):
1 2 3 4 5 6 7 |
let publicDatabase = CKContainer(identifier: "iCloud.com.xxx").publicCloudDatabase let operation = CKFetchRecordsOperation(recordIDs: [recordId]) operation.queuePriority = .veryHigh operation.fetchRecordsCompletionBlock = { (records,e) in ... } publicDatabase.add(operation) |
Here we create a CKDatabaseOperation Subclass, CKFetchRecordsOperation ,It receives a [CKRecordID] Array type,That is,If you wish,,You can query multiple records at once。This kind of treatment you are familiar with direct incoming closure is not the same,But greater flexibility,You have three choices:
-
perRecordProgressBlock
This will be based on each query to return the records you progress,If you want the progress bar, then; -
perRecordCompletionBlock
After this call will succeed in every record; -
fetchRecordsCompletionBlock
This call is completed after the final mission,It returns a [CKRecordID : CKRecord] Type of dictionary record for you to get the specific content。
You will carry out the closure of these three attributes passed,They will be called at the right time。
In short,Finally, we have to set about the task's priority,Adequate resources so that it runs when the child thread:
1 |
operation.queuePriority = .veryHigh |
Such,You can downloadSignificantly fasterGot it。
For Upload(Modify and delete),you can use CKModifyRecordsOperation ,The use of similar,To save on the saved parameters in the form of,To delete,Put it in the form of parameters to be deleted:
1 2 3 |
let operation = CKModifyRecordsOperation(recordsToSave: nil, recordIDsToDelete: [self.record!.recordID]) operation.queuePriority = .high self.publicDatabase.add(operation) |
Just useful fields
Generally not a big data,but,CloudKit non-relational databases,So each record can have one or more fields are used as an accessory - the cloud is logarithmic,Annex is placed in a code table profile,I said above,If direct access to this record,So ios will "kind" to help you put together the line and attachments to a local,If it is a okay,We increased the priority acquired,but,If you want to show a list of what??♂️ simply a disaster。
so,We need to get at the time of the unneeded fields(Especially the larger attachment field)Excluded,Only when needed to download the full contents of the field,Is not it?
Here still we need above used CKDatabaseOperation ,It has a sub-class is CKQueryOperation ,When you write a CKQuery ,Do not rush to execute,Put it CKQueryOperation in,Setting priorities,And called desiredKeys Property,The field names you want to get written into Jiuhaola:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
let predicate = NSPredicate(value: true) let query = CKQuery(recordType: recordType, predicate: predicate) query.sortDescriptors = [NSSortDescriptor(key: "DownloadTimes", ascending: false)] let queryOperation = CKQueryOperation(query: query) queryOperation.desiredKeys = ["Description","Name","DownloadTimes","UploadUserName"] queryOperation.queuePriority = .high queryOperation.recordFetchedBlock = {(record) in ... } queryOperation.completionBlock = { ... } publicDatabase.add(queryOperation) |
Such,To avoid large attachments class,As a result,,Get even hundreds of data,Can easily respond,The same time,Because you can easily get to the data,We also can do fast local inquiry,When you need to download specific attachments,And then load a specific record to complete。
Permissions issue
To note here,In CloudKit DashBoard Lane,Permissions are divided into three categories,They are::
- World
- Authenticated
- Creator
World well understood,Everyone is;Creator is not difficult,It is the creator of the file;The Authenticated bit dizzy - it refers to allSigned iCloud accountPeople。
Here corresponding, World is not logged iCloud account people。
so,If you added a record like "downloads" This counter,Then you should give "Authenticated"Join the authority to write,Of course,This is a little insecure,But for a few clouds here are intended to be shared publicly,So we better the,If you have more stringent security requirements,Then you should go alone what the role of design problems。If you do not have permission to write (no default),So other users can not download count will be updated。
For it CloudKit,If your user is not logged iCloud ,It is also available,But without the authority to write,So these people are not recording a digital download - and because there is no authority Update。
CloudKit production environment
Initial use CloudKit developers might headaches,The blue and green development environment where the difference between the production environment in the end? - The most obvious difference:You use Xcode compiled version will run directly connected to the development of the default version,And you upload to iTunes Connect in the program is the default connection to the production environment。
It is noteworthy that,Even TestFlight ,and alsoUsing a production environment,Only you are using a development environment。
Other,These two environments are independent of content,All the contents of your development environment, testing is not deployed to the production environment which,Only field、The role of other configurations will be deployed in the past。
You can understand,You build a local database,Written table,Well configuration,Then test run through - this time you want to go to the server is configured with,What are you going to do in the past? Your configuration,Your table - does not include your test data,Right?
Original article written by LogStudio:R0uter's Blog » CloudKit Optimization Guide
Reproduced Please keep the source and description link:https://www.logcg.com/archives/2453.html