5

I'm trying to use a ValueTransformer (né NSValueTransformer) in Swift that is being used by the first window that my application opens. Value transformers need to be registered with ValueTransformer.registerValueTransformer(_:forName:) before they can be queried by the user interface runtime.

The documentation for NSValueTransformer recommends registering value transformers in +[AppDelegate initialize]. However, Swift doesn't allow you to override +initialize. I tried to register from applicationWillFinishLaunching(_) and applicationDidFinishLaunching(_), but they both happen too late and my window doesn't get filled because the runtime can't find the value transformer.

Where should I register my value transformer?

zneak
  • 134,922
  • 42
  • 253
  • 328

3 Answers3

6

In AppDelegate you can use a dummy property of type Void with a closure. The closure is even executed before init

private let transformer : Void = {
    let myTransformer = MyValueTransformer()
    ValueTransformer.setValueTransformer(myTransformer, forName:NSValueTransformerName("MyValueTransformer"))
}()
vadian
  • 274,689
  • 30
  • 353
  • 361
3

I found that I can count on the app delegate class to be initialized early and only once, so I stuck my ValueTransformer.registerValueTransformer call in it.

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    override init() {
        ValueTransformer.setValueTransformer(MyValueTransformer(), forName: NSValueTransformerName("MyValueTransformer"))
    }
}
zneak
  • 134,922
  • 42
  • 253
  • 328
2

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.

mschmidt
  • 2,740
  • 4
  • 17
  • 31