Search code examples
objective-cioscore-datamkmapviewmkoverlay

Save MKOverlay objects in Core Data


I have a large MKOverlay that I would like to be saved in Core Data so that I don't have to create it later. Since this isn't one of the types that you can choose in Core Data, how do I go about saving it?

Do I need to somehow encode it first?

Do I then need to decode it when using?

What kind of object do I select in core data when creating a new property?

Thanks guys.


Solution

  • If you do not need to query for different overlays and you're not using core data elsewhere in your project, then you're probably better off caching the overlay on disk as an encoded NSArray.

    However, if you're already using Core Data or you're caching multiple overlays then you can encode/decode the overlay in a field of type NSData. Add additional fields to the entity so you can query for the specific overlay you're looking for.

    In iOS 5, you can enable optional storage of NSData fields in an external file by selecting the "Allows External Storage" option. Core Data will apply a size-based heuristic to determine if a blob or external file will result in better performance.

    MKOverlay conforms to NSCoding, so you can encode and decode an entire array of MKOverlay objects using an encode method of NSKeyedArchiver and store the result in a binary field in your entity. You'll likely want + (NSData *)archivedDataWithRootObject:(id)rootObject on NSKeyedArchiver and + (id)unarchiveObjectWithData:(NSData *)data on NSKeyedUnarchiver

    See the Archives section in the Archives and Serializations Programming guide for details of creating a keyed archive at: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Archiving/Articles/archives.html

    You can write a custom accessor for the entity's binary field that encodes and decodes the overlay array for you. Another option is to create a value transformer that encapsulates the encoding and decoding operations. The end result would be an overlays array property that you can set and read via entity.overlays.