Closed AdithyaReddy closed 6 years ago
The problem happens because use using TyphoonStoryboardDefinition.withStoryboard
which doesn't know about viewController type, returned by storyboard. You should specify it explicit. For that, go into configuration block of categoryListViewController
definition and set autoInjectionVisibility property and use method setClassOrProtocolForAutoInjection
. Let me know if it clear and works for you.
Wow, thanks for the lightning fast response. And yeah, it very well worked :) Thanks a lot.
One last thing to clarify:
`@objc open dynamic func mainNavigationController() -> Any { return TyphoonDefinition.withClass(UCNavigationController.self) { (definition) in
definition?.scope = TyphoonScope.prototype
definition?.injectProperty(NSSelectorFromString("analyticsClient"), with:self.coreAssembly?.analyticsLogger())
}
}
@objc open dynamic func rootNavigationController() -> Any {
return TyphoonDefinition.withClass(**RootNavigationController**.self) {
(definition) in
definition?.useInitializer(#selector(**RootNavigationController**.init(rootViewController:)), parameters: { (method) in
method?.injectParameter(with: self.mainTabBarController())
})
definition?.injectProperty(NSSelectorFromString("navigationBarHidden"), with: true)
definition?.scope = TyphoonScope.prototype
}
}`
Basically RootNavigationController is a subclass of UCNavigationController. RootNavigationController was created just to make typhoon init two definitions of same object type.
The problem here is, I just tried adding 'autoInjectionVisibility' to the above mainNavigationController()'s definition block. But when I tried to access UCNavigationController by type and typhoon threw an error stating that
More than one component is defined satisfying type: 'UCNavigationController' :2 candidates
@alexgarbarev 1) any idea(or a workaround, other than subclassing) how to create 2 definitions for same object type? and 2) Even if I have two definitions(by subclassing), when I try to access them by type, typhoon throws above mentioned error, any workaround for this?
Thanks
That's because access by type includes subclasses in search by default. I.e. you can try to find a UIViewController
and get much more candidates in exception. You should access by key, if your type is ambiguous for Typhoon, or make a new specific subclass for your case and then access by that type.
Makes sense. Will try it. Thank you :)
any idea(or a workaround, other than subclassing) how to create 2 definitions for same object type? and
Even if I have two definitions(by subclassing), when I try to access them by type, typhoon throws above mentioned error, any workaround for this?
-You can access subclass by type, but base class should be accessed by key.
Yeah. Agreed. I went with subclass-each-type-and-access-by-type approach rather than resolve-base-class-by-key approach. Thanks for the clarification.
func getClass<T: AnyObject>(props: [String: Any], type: T.Type) -> T? {
return TyphoonDefinition.withClass(T.self, configuration: {
(definition) -> Void in
props.forEach({ (key, selector) in
definition?.injectProperty(NSSelectorFromString(key), with: selector)
})
definition?.autoInjectionVisibility = TyphoonAutoInjectVisibility.byClass
if let definition = definition as? TyphoonFactoryDefinition {
definition.classOrProtocolForAutoInjection = T.self
}
}) as? T
}
@objc dynamic public func searchCategoryViewController() -> SearchCategoryViewController? {
var properties: [String: Any] = [String: Any]()
properties["homeAssembly"] = self
properties["analyticsClient"] = self.coreAssembly?.analyticsLogger()
properties["searchResultsView"] = self.uiAssembly?.homeSearchView()
return getClass(props: properties, type: SearchCategoryViewController.self)
}
@alexgarbarev I was actually trying to extract out the Typhoon definition part out of the definition into a common function using Swift Generics.
But then I get a crash when the line 'return getClass()' gets executed.
Thread 1: EXC_BAD_ACCESS (code=2, address=0x119c15e58)
Any idea if the problem is with Generics not being properly supported by Objc or is there limitation in Typhoon with regards to the same that am unaware of?
Could you help me with a solution/workaround to this?
@jasperblues @alexgarbarev Thanks
` // Storyboard definition @objc open dynamic func homeStoryBoard() -> Any { return TyphoonDefinition.withClass(TyphoonStoryboard.self) { (definition) -> Void in definition!.useInitializer(#selector(TyphoonStoryboard.init(name:factory:bundle:))){ (initializer) -> Void in initializer?.injectParameter(with: "Home") initializer?.injectParameter(with: self) initializer?.injectParameter(with: Bundle.main) }} }
// ViewController init through storyboard @objc open dynamic func categoryListViewController() -> Any { return TyphoonStoryboardDefinition.withStoryboard(self.homeStoryBoard(), viewControllerId: "categoryListViewController", configuration: { (definition) in definition?.injectProperty(NSSelectorFromString("assembly"), with:self) }) }
//Resolving the ViewController by type private func getClassByType(with factory: TyphoonComponentFactory, type: T.Type) throws -> T {
return factory.component(forType: T.self) as! T
}
`
The problem is when I try to resolve CategoryListViewController by type(which is initialised through storyboard) it crashes. And the exception I get is :
This issue/crash doesn't happen when I resolve through key. It neither poses problem in non-storyboard init'ed viewcontrollers.
Could you please help me resolve-by-type(not by key) for ViewController(using storyboard)? @jasperblues @alexgarbarev
Thanks in advance.