Add Valuetransformer in Swift

Where do I register a ValueTransformer in Swift?

You are right, you can register your value transformers in the AppDelegate. If you want something that closer resembles ObjectiveC's +initialize you can use lazy initialization of a class variable. E.g:

class AppDelegate: NSObject, NSApplicationDelegate {

static let doInitialize: Void = {
// register transformers here
}()

override init() {
super.init()
AppDelegate.doInitialize
}
}

This pattern should also work for classes other than the AppDelegate if you want to keep the transformers things closer to the classes that actually use them.

CoreData ValueTransformer.transformedValueClass() is never called in Swift 3

Apparently, Core Data only supports transforming to NSData. I couldn't find the original documentation for this in the Core Data programming guide but after much searching other users have encountered the same issue.

The idea behind transformable attributes is that you access an
attribute as a non-standard type, but behind the scenes Core Data uses
an instance of NSValueTransformer to convert the attribute to and from
an instance of NSData. Core Data then stores the data instance to the
persistent store.

By default, Core Data uses the NSKeyedUnarchiveFromDataTransformerName
transformer, however you can specify your own transformer if you want.
If you specify a custom transformer, it must transform an instance of
the non-standard data type into an instance of NSData and support
reverse transformation. You should not specify a name if you are using
the default transformer.

Custom NSValueTransformer in xcode 6 with swift

After you initialise newTransformer you should also include the line:

NSValueTransformer.setValueTransformer(newTransformer, forName: "myTransformer")

Then in your Interface Builder you should use myTransformer instead of newTransformer under the Value Transformer dropdown.

Where do I register a ValueTransformer in Swift?

You are right, you can register your value transformers in the AppDelegate. If you want something that closer resembles ObjectiveC's +initialize you can use lazy initialization of a class variable. E.g:

class AppDelegate: NSObject, NSApplicationDelegate {

static let doInitialize: Void = {
// register transformers here
}()

override init() {
super.init()
AppDelegate.doInitialize
}
}

This pattern should also work for classes other than the AppDelegate if you want to keep the transformers things closer to the classes that actually use them.

CoreData: ValueTransformer functions are not called

You haven't overridden the correct methods of ValueTransformer. Your methods are:

func transformedValue(value: String?) -> NSData?
func reverseTransformedValue(value: NSData?) -> String?

The correct methods are:

func transformedValue(_ value: Any?) -> Any?
func reverseTransformedValue(_ value: Any?) -> Any?

The big hint that you're implementing the wrong methods is that you didn't need to add the override keyword.

BTW, this expression:

encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!

can be replaced with:

encoding: .uf8

It would also likely be better to replace your return "nil" with return nil; it's a String?, so it can be nil if things go wrong.

RestKit valueTransformer not being called

So I managed to finally figure out what the problem was.

My podfile was configured to use RestKit 0.20.3. And then I had added RKValueTransformers as another Pod. However, RestKit 0.20.3 and earlier come with their own version of RKValueTransformer (.h and .m) files. And those older versions of RestKit doesn't support adding your own Transformers, because it doesn't make use of the newer RKValueTransformers library.

When I upgraded my RestKit version to the newest version (actually anything above 0.21.0 would work), things started working fine. I didn't need to add the pod RKValueTransformers, because it gets added automatically as a dependency of RestKit.

Where to implement NSValueTransformer for Core Data in Swift

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.



Related Topics



Leave a reply



Submit