Search code examples
swiftmacosdependency-injectiontyphoon

Typhoon: Injecting controllers from storyboard OS X


I have a clean OS X project in Xcode (OS X, Swift, Storyboards). Info.plist has the following config

enter image description here

Here is a configuration for view controller in MyAssembly.sift

public dynamic func viewController() -> AnyObject {
    return TyphoonDefinition.withClass(ViewController.self){
        (definition: TyphoonDefinition!) in
            definition.injectProperty("name", with: "TEST INJECTED")
    }
}

here is my ViewController.swift:

import Cocoa

@objc
class ViewController: NSViewController {
    var name:String?
}

I added NSTextField on the view and bind its value to the ViewController's name property.

According to the documentation it should work, but it doesn't.

When I try to print(NSStoryboard(name: "Main", bundle: NSBundle.mainBundle())) in AppDelegate.applicationDidFinishLaunching method it prints as <NSStoryboard: 0x600000001280>, so, it is not a TyphoonStoryboard instance.

If I add typhoonKey to the User Defined Runtime Attributes on ViewController like this

enter image description here

the the error message "Failed to set (typhoonKey) user defined inspected property on (Typhon_Test_Delete.ViewController): [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key typhoonKey." gets printed.

Any ideas what I'm doing wrong?

May be Typhoon is looking for UIMainStoryboardFile but in this case we have NSMainStoryboardFile?


Solution

  • You're right Typhoon doesn't provide OSX storyboard integration at the present time, only iOS. On iOS, Typhoon:

    • Checks for a TyphoonConfig in your applications plist at startup. If found, along with Storyboard details (UIMainStoryboardFile) then it will instrument the application to ensure that this storyboard is an instance of TyphoonStoryboard.

    Work was started on this OSX support, however didn't complete as there was little demand. It wouldn't be a major undertaking to finish this off.

    In the meantime you could either:

    • Manually create an instance of TyphoonStoryboard and use that.
    • Invoke [factory inject:controller] after instantiation.