Brent Traut Brent Traut - 4 months ago 10
Objective-C Question

How do I set up my Core Data model when my objects have arbitrary property data?

I'm struggling to figure out how to build a Core Data model to support the class structure I've created in my app.

My app has users, and I allow those users to log into the app using multiple different authentication methods. Each authentication method requires slightly different credentials and cred types. I've chosen to solve this by creating an abstract

AuthenticationSettings
base class, then subclass it with
FacebookAuthenticationSettings
,
TwitterAuthenticationSettings
,
MyWebsiteAuthenticationSettings
, etc.

My
User
class has a property
authSettings
(of type
AuthenticationSettings
), that stores an instance of one of the settings classes. Users are allowed only one auth method per user, so this works great.

The question is, how do I create a Core Data model for my users given that
authSettings
can have one of many object types stored to it?


  • Do I create separate entities for each type of authentication and then create relationships between those entities and the user entity? This is strange because the data model doesn't enforce 1:1 auth method to user. When fetching users, I'd also have to fetch their corresponding auth methods.

  • Do I just create my own serialization encoding of the auth creds and jam it into a string field on the user entity? This forces me to invent some encoding which feels especially messy if any future auth methods use fields that are difficult to serialize to string.

  • Is there a better way?


Answer

One way is to set up a Core Data entity hierarchy that parallels your class hierarchy. Create an abstract entity in Core Data called AuthenticationSettings and create a series of sub-entities for each authentication type. As with your User class property, create a relationship to AuthenticationSettings.

A simpler approach that sounds like it would meet your needs would be to make your various authentication classes conform to NSCoding, and then just store them in a single "transformable" (not string) field on the user entity. Core Data would then convert the authentication object to/from NSData automatically.