Displaced Hoser Displaced Hoser - 4 months ago 171
Swift Question

Where to implement NSValueTransformer for Core Data in Swift

I'm trying to put entities in a Core Data store that each have non-standard data types - one is an NSDocument and the other is an NSURL. I get that within the .xcdatamodeld I need to declare them as Transformable. And I think I need to add something that implements NSValueTransformer to turn them into NSData (... or is there a default transformer that will do that automatically?)

I think the question should be simple to answer: where do I implement it? I haven't found an explicit example of doing this in Swift. There's an Objective-C example but the separation of .h and .m files makes it unclear to me where this would go in Swift.

Suppose I have an entity type called Notebook with an attribute called folderURL - of type Transformable in the database, and of type NSURL in the actual variable. (I'm using that as the example because it's the simpler one - please don't tell me to just convert the NSURL to a String, because that won't work for the other Transformable.)

Question is: where do I put the NSValueTransformer for folderURL, assuming that I need one? Should Notebook implement it? Should Notebook+CoreDataProperties? Or do I need a separate subclass called FolderURL that implements it, and if so, how do I refer to that subclass back in Notebook (and/or Notebook+CoreDataProperties)?

(There was an earlier question with a similar title but they seem to have got a bit further than this already - they're not asking or demonstrating about the "where".)

Answer

The "where" is just anywhere in your project. Anywhere that ensures that your NSValueTransformer subclass will exist at run time. Implement the NSValueTransformer subclass, and enter the class name in the Core Data model as the value transformer.

However there is a default transformer. Any class that adopts the NSCoding protocol can be automatically transformed by Core Data. In that case you mark the attribute as transformable but don't include a class name. This includes NSURL, so you don't need to transform that or convert it to a string.

For your NSDocument subclass then, you have the option of either implementing NSCoding in the class or of implementing an NSValueTransformer subclass for the document type.