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:
However there's an important difference between Typhoon Objective-C and Typhoon Swift:
Objective-C:
TyphoonComponentFactory
simply by casting it to one of your assembly interfaces. Swift:
AnyObject
. Swift's strict type-checking won't allow otherwise. This is shown in the Quick Start guide for Swift . 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:
TyphoonComponentFactory
can't be casted to an assembly interface . (Bootstrapping Typhoon via an app's plist will remain a valid way). 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.