I’m slowly beginning to like Core Data

Core Data is by far the worst framework I have ever had to work with. Or is it?

It has a steep learning curve. Though once you’ve got your head around it, it doesn’t seem so bad after all.

I’m really starting to get accustomed to it. There are just some principles one needs to know in order to really not hate it.

I use the MagicalRecord library on top of it, and the mogenerator tool to make everything manageable.

I’ve got multi-threaded code and it cooperates (so far).

My approach is to keep most update operations off of the main thread, and saving that background context will update the main thread context, which in turn updates all the NSFetchedResultsControllers, and now my table views just animate those changes nicely!

I think, after numerous attempts, I am finally getting to be fit with CoreData and now can use it as my main persistence framework from now on. (Until they scrap it and move for something more Swift-style…)

Advertisements

Transformable Attributes in Core Data

The way I tend to use transformable attributes in Core Data is to just make use of the standard NSValueTransformer that gets used to encode/decode any object that conforms to the NSCoding Protocol, then in my NSManagedObject subclass, cast this to the type it’s expected to be (I use mogenerator to generate the subclasses by the way):

name it with suffix Object since it will have type id

name it with suffix Object since it will have type id

  @interface MyObject : _MyObject
  
  @property (nonatomic, strong) NSDictionary *metadata;
  
  @end

And then in the .m file, the accessors

  @implementation MyObject
  
  + (NSSet*)keyPathsForValuesAffectingMetadata
  {
      return [NSSet setWithObjects:@"metadataObject", nil];
  }
  
  - (void)setMetadata:(NSDictionary *)metadata
  {
      [self willChangeValueForKey:@"metadata"];
      self.metadataObject = metadata;
      [self didChangeValueForKey:@"metadata"];
  }
  
  - (NSDictionary*)metadata
  {
      [self willAccessValueForKey:@"metadata"];
      NSDictionary *metadata = (NSDictionary*)self.metadataObject;
      [self didAccessValueForKey:@"metadata"];
      return metadata;
  }
  
  // the rest of your implementation here...
  @end

Summary: Saving your custom object classes in CoreData is pretty straightforward when supporting the NSCoding protocol. It’s then easy to ensure typing by declaring properties that just wrap these Core Data attributes. This post is basically something of a recipe so I can remind myself later.

UPDATE:  See this post.  You can actually get mogenerator to set the data type for you and you don’t have to write these accessors at all.

Taking the pain out of CoreData

So far, if I have to make an App that uses CoreData, I will without question be using mogenerator and MagicalRecord.

Here are some links for mogenerator:

https://github.com/rentzsch/mogenerator

And then for MagicalRecord:

http://yannickloriot.com/2012/03/magicalrecord-how-to-make-programming-with-core-data-pleasant/

http://ablfx.com/blog/article/2

https://github.com/magicalpanda/MagicalRecord

They’re worth reading and checking out. CoreData does not seem like such a pain anymore.

Just remember:
* One NSManagedObjectContext per thread. So, if you are doing asynchronous work, save your context to the store on that other thread, then in your main thread callback, make sure you’ve passed an array of objectId’s (NSNumbers) so you can fetch those objects on the main thread.

I’m assuming you’re using CoreData for fairly simple purposes in mobile apps. Not really talking about editing apps with undo managers, etc. Just basic persistence and fetching and so on.