Search code examples
objective-ccore-datamagicalrecord-2.2ensembles

Where do I place the Ensembles uniqueIdentifier?


I have an app that has threee (3) entities in a CoreData store managed by MagicalRecord; I have one (1) managedObject for the whole app. On page 28, the book states:

“Assuming you have added a uniqueIdentifier attribute to your managed objects,”

Does this mean that I need a uniqueIdentifier for each of the entities, or will one do? If I only need one, which entity should I put it in, or doesn't it make any difference. (the example only has 1 entity, hence the question) :-}


Solution

  • Each entity needs an attribute for the unique identifier. The value should be unique for each instance of that entity.

    The value of the unique identifier must be unique among other instances of the same entity type.

    If you have three entities, Entity1, Entity2, and Entity3 then you can have an instance of Entity1 with identifier '42' and an instance of Entity2 with identifier '42 and another instance of Entity3 with identifier '42' without causing any problems.

    EDIT

    You say each entity needs an attribute... which should be unique for each instance of that entity. The value must be unique among other instances... but then you give examples of Entity1, 2 and 3 where the identifier is the same for all three! I'm confused... – SpokaneDude

    That's correct. Entities describe the attributes and relationships for a class of managed objects (which is why the class that represents an entity is named NSEntityDescription). The entity itself is not a managed object.

    So, for each entity defined in your model, you need to have a unique identifier attribute. The value of that unique identifier must be unique among instances of that particular kind of entity.

    If you have 100 instances of Entity1 then each of those instances must have a different value for the unique identifier, relative to all other instances of Entity1.

    If you have 100 instances of Entity2 then each of those instances must have a different value for the unique identifier, relative to all other instances of Entity2 but they don't have to be unique among the identifiers for the instances of Entity1 because the identifiers must be unique per-entity.

    OK, one last question (I hope). The app is for bookstores; does each unique bookstore have one (1) UUID that they share amoung the different employee's iPads? and if I have another app (say for barbershop scheculing), is the UUID different than the bookstore's UUID? And lastly, does the UUID value ever change for a particular bookstore? – SpokaneDude

    So, I assume your core data model has an entity named Bookstore with some number of attributes. You need to make sure that one of those attributes will uniquely identify each managed object instance of entity Bookstore.

    If you have an attribute name and you know for certain that you will never have two Bookstore instances with the same name, then you can use name as your unique identifier.

    However, if there is the possibility that there may be more than one object instance that may have the same attributes, yet still represent a different object, then you need a special attribute whose sole purpose is to guarantee uniqueness.

    For example, let's say your application sucks down JSON data from a server. At the same time, your user runs the app on their iPad and iPhone. They both read a record that describes a Bookstore with name "Bob's Books" and address "42 Mall Drive."

    Each device creates the instance in their local database.

    When it comes time to synchronize those two instances, how does the synchronization algorithm know if you have two completely different objects with the same value, or if you have two copies of the exact same object?

    That's where the unique identifier comes in. You tell the ensembles framework which attribute of each entity can be used to tell if the objects are really the same or not. Then, when it sees two different objects, it can look at the unique identifier and determine if the two objects are really the same object, or if they are two completely separate instances.

    Thus, for each entity, you need to either ensure that one of the attributes can always be used to uniquely identify objects in this manner. If you don't have such an attribute in your model, then you should add one for the entity, and make sure that the attribute is unique among instances of that particular entity.

    The unique identifier only has to be unique among instances of the same entity, within the same database. However, when I have not had a certain unique attribute, I have been using NSUUID to generate my unique identifiers.