简体   繁体   中英

Injecting a view controller from a storyboard using Typhoon and Swift

What is the proper way to inject a UIViewController instantiated from a UIStoryboard using Typhoon and swift?

I can't find any clear examples of this in either of the sample apps, and when I translate the Objective C code from the documentation it throws an exception.

Below is the code from my AppAssembly:

public dynamic func loginViewController() -> LoginViewController {
    return TyphoonDefinition.withClass(LoginViewController.self) {
        (definition) in

        definition.injectProperty("socialClient",with:self.coreComponents.socialClient())
        //definition.scope = TyphoonScope.Singleton
    } as LoginViewController
}

And this is the exception that gets thrown:

0x10636ca1c:  jne    0x10636ca10               ; swift_dynamicCastClassUnconditional + 48
0x10636ca1e:  leaq   0x36b3d(%rip), %rax       ; "Swift dynamic cast failed"
0x10636ca25:  movq   %rax, 0xb4a2c(%rip)       ; gCRAnnotations + 8
0x10636ca2c:  int3   
0x10636ca2d:  movq   %rdi, %rax
0x10636ca30:  popq   %rbp
0x10636ca31:  retq   
0x10636ca32:  nopw   %cs:(%rax,%rax)

The "Swift dynamic cast failed" leads me to believe that what was possible using Objective C is just not possible using Swift.

Has anyone been able to make this work? Any assistance would be greatly appreciated. The library looks really nice and I really want to use it.

The following rules apply using Typhoon in both Swift and Objective-C:

  • At build-time your assembly interfaces return recipes for assembling an object instance. This includes configuration along with any collaborating components.
  • At run-time the assembly interface returns components built according to those recipes.

However there's an important difference between Typhoon Objective-C and Typhoon Swift:

Objective-C:

  • In Objective-C we recommend that your assembly interfaces declare to return the type that will be built, as this provides better code-completion and avoids unnecessary casting.
  • In Objective-C, you can have any of your assembly interfaces 'pose' in front of a TyphoonComponentFactory simply by casting it to one of your assembly interfaces.

Swift:

  • Unfortunately in Swift your assembly methods must return type AnyObject . Swift's strict type-checking won't allow otherwise. This is shown in the Quick Start guide for Swift .
  • In Swift its not possible to cast a TyphoonComponentFactory to one of the assembly interfaces. However its still possible to inject the assembly into a component as follows:

Injecting the Assembly:

dynamic func appDelegate() -> AnyObject {
    return TyphoonDefinition.withClass(AppDelegate.self) {
        (definition) in

        //The type of this property can be TyphoonComponentFactory or any of your 
        //assembly interfaces. 
        definition.injectProperty("assembly", with: self)
    }
}

Fixing your crash:

Therefore to fix the crash by obeying the above conditions, change your code to the following:

Change your code to the following:

public dynamic func loginViewController() -> AnyObject {
    //etc
}

Resolving Components from Storyboard:

As long as your start Typhoon using plist integration and include the usual UILaunchStoryboardName and UIMainStoryboardFile , then Typhoon will ensure your storyboard is an instance of TyphoonStoryboard , this works like a normal storyboard with the added behavior that dependencies are injected according to rules in your assembly.

Documentation for this feature is here .

The following features will be coming soon:

To answer my own question and for anyone else out there with the same issue, make sure that your module is set and pay careful attention to the console log, any errors that might say "unknown view controller"

In your ApplicationAssembly, don't cast the view controller to it's strong type, leave it as AnyObject as is quoted in the documentation.

界面生成器

Thanks to the authors of Typhoon for writing such an awesome framework!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM