I'd like to be able to download a list of all CKRecordIDs of a certain record type from a Cloud Kit database. I don't want the records themselves, since they have large assets that aren't needed until the user asks for them.
CKQuery seems to return CKRecords only. Any ideas?
For this you could use a CKQueryOperation and set the desiredKeys to the fields that you do want to return. I'm not sure if you can set it to an empty array. Since you only want the CKRecordID's and those are already in the meta data you would not need any fields. If it does not work, then just fetch one small field.
Related
I'm developing an application in Quasar/Electron and using Dexie/IndexedDB for my database. I want to find all distinct records in the database that contain both my Event ID and a Dog ID (both key indexed fields). I am able to do this with the following code:
await myDB.runTable
.orderBy('[fk_event+fk_dog]')
.eachUniqueKey((theDuo) => {
this.runsArray.push({eventID: theDuo[0], dogID: theDuo[1]})
})
I'm using a combined key which is working well. However, I need to have more of the records than just the keys. I need a few more fields, is this possible?
I was trying to get records with the unique key function while also using the where function, but that doesn't seem to work.
I need to get all the unique (distinct?) dogs in the table that are in a particular event. And also get their corresponding information. I'm not sure if there is a better, more efficient way to do this? I can always pull out all the records and loop through them to build a custom array, I was just hoping to do this at the table read level. (yeah I'm still in tables/records even though these are collections etc. :p ).
Even the above code gives me all the events, and I can pull out what I need with a filter. I just was thinking it would be faster and more efficient to do it at the read level.
this.enteredRuns = this.runsArray.filter((theEvent) => {
return ( (theEvent.eventID == this.currentEventID) )
})
Try
await myDB.runTable
.orderBy('[fk_event+fk_dog]')
.clone({unique: "unique"})
.toArray()
I know this isn't documented but it should do the work to use unique cursor while still extracting the whole objects and not just the keys. You cannot combine with where but you could use .filter. Just be aware that not all records with be scanned as it will jump over records with same keys - selecting the first visited records only.
I want to store group of data into user defaults so that deleting that group deletes all the data in it. For example i want to store login related data in USER_DEFAULTS_LOGIN and all subscription related data in USER_DEFAULTS_SUBSCRIPTION. Now if I delete USER_DEFAULTS_LOGIN group it does not affects USER_DEFAULTS_SUBSCRIPTION group. This was possible in android preference as creation of preference requires name. I guess there should be similar solution in ios. I have heard of 'domains' and 'suits' but does not understands there purpose. Kindly help.
UserDefaults API provides a way to set data for a key. In your example, you would define your keys to be USER_DEFAULTS_LOGIN and USER_DEFAULTS_SUBSCRIPTION. The data you associate with those keys can be one of several types - bool, number, string, URL, date, array, dictionary, or a bag-of-bytes (NSData).
See https://developer.apple.com/reference/foundation/userdefaults for more details on types and API usage.
In Parse.com, the help document for updating an object seems to require a query first to retrieve the object before one can update the meta data.
Given that I know the objectId of the object I am updating, do I still have to make this additional call to retrieve everything else about the object before I can send an update call (via saveInBackground)?
Yes, you do. In order to update an object from parse, you must have a local copy.
In order to make a call to update an object - which can take several forms of save or saveInBackground or saveEventually, etc. - you must first make a query to have a copy of the object.
If you know the objectId, is sounds like you have already run a query on an associated object - why not get the full object then with an includeKey: call? https://www.parse.com/docs/ios_guide#queries-relational/iOS
I have the following predicate:
let predicate = NSPredicate(format: "NOT (recordID in %#)", recordIDs)
-- recordIDs is an array of CKRecordID objects corresponding to the CKRecords on the device
...that produces a runtime error about the predicate. If I change the predicate format string to something else, the query runs fine. I have the "Query" checkbox checked for all the metadata for this record type in CloudKit.
According to CKQuery documentation:
Key names used in predicates correspond to fields in the currently evaluated record. Key names may include the names of the record’s metadata properties such as "creationDate” or any data fields you added to the record.
According to CKRecord documentation, these are the available metadata for querying:
recordID, recordType, creationDate, creatorUserRecordID, modificationDate, lastModifiedUserRecordID, recordChangeTag
You can use the creation date:
NSPredicate(format: "creationDate > %#", dateLastFetched)
After you pull the records down to the device and save them, save the dateLastFetched and use it for subsequent fetches.
Edit: Be sure to enable the creationDate query index on the CloudKit dashboard (it is not enabled by default like many other indexes)
This is an old question, so I'm not sure if it existed at the time, but the correct way to do this now is to use Apple's built-in server change token support.
Making a giant query including all existing record ID's on the device is going to be slow, and picking a date is going to be imprecise.
The right way to do this is to use CKFetchRecordZoneChangesOperation and pass in a CKServerChangeToken using the operation's configurationsByRecordZoneID property.
The first time you call, pass a nil change token. As records are received, CloudKit will call recordZoneChangeTokensUpdatedBlock with the latest change token. Persist the latest token so the next time you need records from the server, you can just pass in your most recent token and get only what's changed since then.
Enable the meta data index by clicking here:
I'm using Parse as the backend for my app. My app will be used in the field where service will nonexistent or spotty at best so I need to store information offline. I currently save data for the user in a plist in the background (Title, location coordinates, notes, additional data). Since Parse's current iOS offline saving is fairly poor (From what I've read), I was hoping to get around it by creating an array or dictionary from the plist and upload that to Parse by giving it an array once the user is back in cell range.
As it occurs now, when I upload the array, it simply puts the entire contents of the array in a single cell in the database. Is there a way to parse the array and create a new row for each entry/object in the array?
I may have overlooked a better way to do this. If someone has a suggestion I would appreciate it!
I solved it. I iterated through the array using a for loop and added each index as a separate object.