1
votes

I have a few controllers and used Typhoon to inject an object as a property into these controllers. I used Plist Integration. I found that sometimes the object was not injected into the view controllers as expected.

For example, MainTabBarController is the initial view controller and SplashViewController is some other view controller. I have injected the object as the property in the code. The object is verified to be injected into the MainTabBarController.

At some point, I need to present the SplashViewController from the MainTabBarController as follow:

SplashViewController *vc = [[UIStoryboard storyboardWithName:@"Main" 
                                                      bundle:[NSBundle mainBundle]] 
                     instantiateViewControllerWithIdentifier:@"SplashNavigationController"];

[self presentViewController:vc
                   animated:YES
                 completion:nil];

When I tried accessing the object in SplashViewController, it failed. The property does not contain the object.

After some investigation, I found that the storyboard I obtained by calling [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] was NOT a TyphoonStoryboard, but that of MainTabBarController is a TyphoonStoryboard. I therefore changed it to:

SplashViewController *vc = [self.storyboard 
                     instantiateViewControllerWithIdentifier:@"SplashNavigationController"];

[self presentViewController:vc
                   animated:YES
                 completion:nil];

And then the SplashViewController contains the injected object. I would like to confirm if this behaviour is expected and this is the correct approach to handle this kind of problem.

Many thanks!

1

1 Answers

1
votes

Yes, this is the expected behavior. If you use plist integration:

  • The storyboard (if any) defined as UILaunchStoryboardName in your application's plist will be an instance of TyphoonStoryboard, which works just like an ordinary story board with the added benefit that dependencies are injected according to the assemblies defined in your plist.
  • Programmatically creating additional storyboards, as some people do, for example, to split Storyboards into use-cases, requires an instance of TyphoonStoryBoard for dependency injection to occur.

If you wanted to define that storyboard in an assembly you could do something like:

- (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]];
            }];
    }];
}

And provide this storyboard to whatever component needs it.