Reputation: 21880
I've got an app which uses a proprietary method of syncing data from the app to the server and back out to any other app that user is using (iOS and Android).
I'm not using iCloud syncing and I don't want to use iCloud Core Data syncing, so I just want to make it clear that I'm NOT trying to do that.
When the app is uploading a new record to be created on the server, it sends up the URIRepresentation
of NSManagedObect.objectID
which the documentation says is A compact, universal identifier for a managed object
, so that the server can detect if it has already seen this record before (perhaps the app already tried to upload this data, but something failed later on in the process, so this helps us avoid creating duplicate records on the server).
Here is an example of the object id: x-coredata://80978028-AEB5-45F0-AAD5-F328C4B294AF/MedicineShot/p1481
According to the documentation, this object id is supposed to be unique for my app... but I can't really tell what the scope of the uniqueness is, for example, if one person has my app on an iPhone and an iPad, will it generate the same object id in those two different stores on two different devices?
We've been running this app/server for 6 years and we've never had an id conflict, that we know of, but we appear to have run into one.
A user created a record on their iPhone with the above example coredata id. That same user, 5 days later, created a new record on their iPad and it has the exact same coredata id. Since our sync server uses that id to determine if it is receiving a request to create a record that it has already created, the server treated these two different records as the same.
We've never seen this before and the documentation seems to say that this shouldn't happen because these ids should be unique. The Managed Object Id is supposed to be a universal id for a managed object, but these are two different devices creating two different records on two different days (5 days apart)... with the same id.
It was the same user, who is probably using the same Apple Account on both devices.
Could iCloud be secretly copying the persistent store files from one device to another?
If so, is there a way we can prevent iCloud from copying those persistent data store files so that we can ensure we're getting unique ids from device to device?
EDIT: The object id uri has what appears to be a UUID of 80978028-AEB5-45F0-AAD5-F328C4B294AF
and UUIDs are supposed to be Universally Unique as the name says. Is that part of the object id a UUID? If so, how can the Core Data persistent store on two different devices produce the same object id uri?
Upvotes: 1
Views: 137
Reputation: 70976
Despite what the documentation suggests, managed object IDs are only unique within a specific persistent store file. They're not guaranteed to be unique everywhere. I know, I've read the docs too, and I know they say "universal"-- but I think it's also important to note that they say
Identifiers contain the information needed to exactly describe an object in a persistent store...
But they don't say anything about multiple persistent stores. Core Data was originally created for use within an app, and the docs have not always kept up with the idea of syncing to servers or other devices.
The form of the URI-- x-coredata://80978028-AEB5-45F0-AAD5-F328C4B294AF/MedicineShot/p1481
-- is undocumented, but the parts are:
MedicineShot
: The entity used for this instancep1481
: p
implies "permanent" (temporary IDs have a t
and a different format), and 1481
is basically an incrementing primary key within the persistent store. It starts at 0 and counts up every time you insert a new instance of the entity.Using a managed object ID from one store in another store is unlikely to work well. Apart from the UUID, the unique IDs won't match unless you're very careful to always insert new instances in the same order.
Upvotes: 2