0

I'm building a simple app in Swift using Core Data and trying to decide if I should store a unique id in my entities. In my research, I have found examples of that do and examples that don't, but I haven't found any clear reasoning behind this kind of decision.

Please note: - I come from a RDBMS background and I know that Core Data is an object graph, not a relational db - I do know that Core Data creates an NSManagedObjectID, but how do I determine if that will be enough

I see threads like this (from 7 years ago, by the way) which lays out these options:

  • Use -[NSManagedObject objectID]. Note that this ID is temporary until either the object is saved for the first time or you call
  • [NSManagedObjectContext obtainPermanentIDsForObjects:error:] Use the CFUUID family of functions to generate a UUID for each object in your -awakeFromInsert method
  • Create your own primary key-like system that stores an integer in your model and increments it with the creation of each object

but I haven't been able to find much information about which options are appropriate for which situations.

What questions should I be asking myself to figure out if Core Data's unique identifier (NSManagedObjectID) is all I need or if I should go beyond that and choose to include one of my own into the mix.

Community
  • 1
  • 1
Jim
  • 1,260
  • 15
  • 37
  • I'm not a Core Data coder (only dabbled with it), but I've always thought there were two possible "sources" for the model - mySQL or an XML file. Being an MSSQL person myself in a past lifetime, I'd think any DB design you like would suffice for an answer. In fact, there's arguments I've read that CD is sometimes an unnecessary layer and using a straight mySQL design streamlines things. (Those arguments sometimes claim that CD biggest strength is persistence.) –  Jan 09 '17 at 01:19

2 Answers2

0

if Core Data's unique identifier (NSManagedObjectID) is all I need

Need for what purpose exactly?

Core Data maintains its object's primary keys internally, so you basically don't need to implement them yourself. In CD you interact with objects that already have a mechanism to establish relationships. You just have to assign one NSManagedObject to a property of another NSManagedObject and that will represent a O2O or O2M relationship like this:

anotherObject.parent = oneObject;

For many- side there will be a set for that. Have a look at the documentation.

The only scenario when you need some sort of foreign keys is when you syncing your data with some web-service.

You may be interested in this post if you need to store a reference to some particular NSManagedObject in user defaults.

And by the way, there is [[NSUUID UUID] UUIDString].

Community
  • 1
  • 1
bteapot
  • 1,897
  • 16
  • 24
  • I was thinking of a few purposes like 1) I have a `UISegmentedControl` that controls some user default choices and making the unique ids of those 0 and 1 make it very easy to set/change the selected value of that control and store the index value in `NSUserDefaults` 2) avoid matching things by using `String` in many cases (not for determining relationships though) and 3) it seems it would be easier to change, say, the 'description' property of a particular unique record that might be the 'one' in a 'one-many' down the road after my app is released. – Jim Jan 09 '17 at 15:38
  • And then I also see really smart Apple guys (https://vimeo.com/140037432) who have used something like `newTask.setValue(NSUUID().UUIDString, forKey: "id")` in their examples so it makes me think there has to be a good reason. – Jim Jan 09 '17 at 15:41
  • `NSManagedObjectID` refers to a specific object in a specific store. So you can safely use it if you have no need of exchanging data with some external application. See the [Overview](https://developer.apple.com/reference/coredata/nsmanagedobjectid?language=objc#overview) section of documentation. – bteapot Jan 09 '17 at 16:04
0

The only reason to use your own unique IDs with Core Data is if you ever sync the data to another device or web service. NSManagedObjectID is sufficient for local use but they don't work well for syncing. For example, if you get data from your back end server, it probably has unique IDs, but you can't force Core Data to use them. Likewise even if your syncing is to another iOS device, you can't force Core Data on the second device to use the same NSManagedObjectID as on the first.

For local use, NSManagedObjectID is all you need. If you need to save a reference to a managed object in user defaults, you can store that. Later you can use object(with:) or existingObject(with:) to quickly retrieve the managed object.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • At the risk of stating the obvious, Tom, you're saying that if I were to later add the ability to sync across iOS devices using iCloud, I need to manage my own unique IDs. Correct? – Jim Jan 12 '17 at 14:45
  • Yes, because you can't use the `NSManagedObjectID` on the server side of things. You need some other ID to tell the server what you're updating, or to make sense of incoming data from the server. – Tom Harrington Jan 12 '17 at 18:01