Kenny Wyland
Kenny Wyland

Reputation: 21880

Does iCloud silently copy Core Data persistent store files from device to device? non-unique NSManagedObjectId?

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

Answers (1)

Tom Harrington
Tom Harrington

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:

  • UUID: An identifier for a specific persistent store. This is also saved in the persistent store's metadata, so that instances and stores can be matched.
  • MedicineShot: The entity used for this instance
  • p1481: 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

Related Questions