Search code examples
swifttyphoon

How to use multiple storyboards defined in assemblies?


I'm using different storyboards for different use-cases. My question is how can I instantiate a storyboard, a view controller by it's storyboard identifier and connect it to the actual viewcontroller class?

Here's where I am right now:

public dynamic func loadingViewController() -> AnyObject {
    return TyphoonDefinition.withClass(LoadingViewController.self) {
        (definition) in

        definition.injectProperty("presenter", with: self.loadingPresenter())
    }

//        return TyphoonDefinition.withFactory(self.storyboard(), selector: "instantiateViewControllerWithIdentifier:") {
//            (factory) in
//            
//            factory.injectParameterWith("LoadingViewController")
//            
//        }
}

public dynamic func storyboard() -> AnyObject {
    return TyphoonDefinition.withClass(TyphoonStoryboard.self) {
        (definition) in

        definition.useInitializer("storyboardWithName:factory:bundle:") {
            (initializer) in

            initializer.injectParameterWith("Loading")
            initializer.injectParameterWith(self)
            initializer.injectParameterWith(NSBundle.mainBundle())
        }

        definition.scope = TyphoonScope.Singleton
    }
}

In this example the storyboard's name is 'Loading', the viewcontroller is 'LoadingViewController' and the storyboard identifier is also 'LoadingViewController'.

Any help (or example code) would be appreciated!


Solution

  • To create a TyphoonDefinition representing a UIViewController that will be emitted from a storyboard:

    Create a definition for the storyboard:

    - (UIStoryboard *)storyboard
    {
        return [TyphoonDefinition withClass:[TyphoonStoryboard class] 
            configuration:^(TyphoonDefinition *definition) {
    
            [definition useInitializer:@selector(storyboardWithName:factory:bundle:)
                parameters:^(TyphoonMethod *initializer) {
                    [initializer injectParameterWith:@"StoryboardName"];
                    [initializer injectParameterWith:self];
                    [initializer injectParameterWith:[NSBundle mainBundle]];
                }];
        }];
    }
    


    If you'd like to instantiate the controller marked as the 'initial' controller in the storyboard:

    - (UIViewController *)initialControllerFromStoryBoard
    {
        return [TyphoonDefinition withFactory:[self storyboard] 
            selector:@selector(instantiateInitialViewController)];
    }
    


    If you'd like to instantiate another controller in the storyboard:

    - (UIViewController *)arbitraryControllerFromStoryboard
    {
        return [TyphoonDefinition withFactory:[self storyboard] 
            selector:@selector(instantiateViewControllerWithIdentifier:)
    
            parameters:^(TyphoonMethod *factoryMethod) {
                [factoryMethod injectParameterWith:@"ViewControllerId"];
            }];
    }
    

    Sorry for replying in Objective-C, but I haven't got my Swift chops on at the moment.