UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: UUID in core data

Forums > SwiftUI

Understanding that core data creates a specific unique key for each core data entry that is unique to each entity in the background, when and or why would a developer need to add a unique attribute for a core data entity to uniquely identify it for code? Shouldn't a developer be able to identify a core data entry using the already supplied unique key? why doesn't Apple make this identification an automatic public usable attribute?

Dave

3      

hi,

sorry for the length of this response ... i did not expect it when i started to reply (!)

i generate UUIDs for each Core Data entity for a few reasons (naming the field id so i get Identifiable for free)

(1) from time to time in my iOS app -- mostly for development purposes -- i export all Core Data content on a physical device to .json files, and save them somewhere (i can share them/email them to me for use back on my Mac).

seems a little bizarre, perhaps; but until i get the app where i want it, until i really do believe that NSPersistentCloudKitContainer works, and until i can read that CloudKit data from a companion MacOS app (not yet written), i want to be sure that i have a backup of the Core Data content from a working device.

better, i can also re-use those .json files as seed data for updated versions (especially in cases where the Core Data model has changes -- just delete the existing app, download the new version which re-populates the Core Data store from the saved data -- and this avoids having to go through migration).

my method of reducing all Core Data content to .json files then requires capturing all the relationships. and for this i rely on having UUIDs.

example: if an entity Employee (which has an id: UUID) has a to-one relationship to a Department (which also has an id: UUID, and the inverse relationship would be to-many) then i can form a mirror-image EmployeeJSON struct to have all the simple attributes of an Employee, plus a variable called departmentID = the UUID of the Department in the relationship. the corresponding DepartmentJSON struct would be written with its content, but with the inverse relationship ignored.

when later reading the .json files to repopulate the Core Data content, just create all new Employee and Department entities; then for each Employee, find the Department that matches the employee's departmentID and re-establish the employee-department relationship.

(2) i prefer owning the id, rather relying on Core Data to identify entities. an NSManagedObject does have an objectID attribute, but it's not a simple UUID, so how to save this and then re-establish the Core Data store is an investigation that's best left to someone that's not me.

(3) i also use UUIDs to keep the Core Data model a little flatter and the Core Data store more lean.

that is, rather than having relationships all throughout the object graph, it's sometimes sufficient in my case to record the UUID of one object B in another object A, instead of having a Core Data "one-to-many relationship pointer" from A to B. entity B no longer needs an NSSet? data type to record the inverse relationship. if i need to match up the appropriate B entity with A later, i can do a fetch for entities of B's type with their id: UUID matching A's UUID reference for B.

why would you do this? here's my example:

8 bridge Players get together to play cards for an afternoon bridge Session. the Session consists of a number of Hands -- in this case, four teams of two players each are playing a round-robin format across two tables. if we go full-out data model relationships, we see that each Session has Players (to-many), each Hand has Players (to-many), and each Session has Hands (to-many).

however, i'll implement only the last of these as a relationship (it's a true "Session owns the Hand" relationship). for the others, i'll record only the UUIDs of the Players in a Session in the Session entity (transformable, as playerIDs: an array of UUID), the UUIDs of the Players playing a hand in a Hand entity (also transformable, as playerIDs: an array of UUID).

so:

-- given a Session, i can find its players by fetching all Players (in practice, this number is small) and pulling out those i need by their id; and i can find the hands in the Session directly in Core Data.

-- given a Hand, i can find its session directly in Core Data, and i can find its players by fetching all Players and pulling out those i need by their id.

-- given a Player, i do a fetch to find all sessions and filter by those the player played, and then look through the hands in each Session to find hands the player played.

if i implemented true Core Data relationships for Hand <--> Player and Session <--> Player, the Player entities are going to have a very large footprint! each Player would contain references back to every Session played and every Hand played. for just one Session, there could be references maybe 20 hands. play 30 or 40 or 50 sessions over the course of several months, and each Player entity will be darn bloated in memory.

oh, and there's one more thing on this last point. implementing all three relationships among Hand, Session, and Player in the Core Data model creates a confusing, circular pattern in the model's visual diagram. think carefully about how to delete entities (e.g., what would "cascade" mean as a delete policy).

again, sorry for the length of the reply ... although i think i actually learned something in trying to write this all out for you.

hope that helps, DMG

6      

Thank you for the response, it resembles a lot of what I was already thinking but not sure what the standard is.

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.