1
votes

I have tested Typhoon using storyboards and plist integration, defining the dependencies in my assembly and worked as expected. The dependencies on ViewControllerB are being properly injected for example when a push segue is performed from ViewControllerA to ViewControllerB. I have seen that instantiateViewControllerWithIdentifier is swizzled to inject the properties.

However, I also have legacy code that don't use storyboard. It uses XIBs. For example, LegacyViewControllerA pushes LegacyViewControllerB:

This is the code in LegacyViewControllerA:

LegacyViewControllerB *legacyVCB = [[LegacyViewControllerB alloc] initWithNibName:@"LegacyViewControllerB" bundle:[NSBundle mainBundle]];
legacyVCB.paramOne = ...
legacyVCB.paramTwo = ...
[self.navigationController pushViewController:legacyVCB animated:YES];

This is the assembly:

- (LegacyViewControllerB *)legacyVCB
{
    return [TyphoonDefinition withClass:[LegacyViewControllerB class]
                          configuration:^(TyphoonDefinition *definition) {
                              [definition injectProperty:@selector(apiClient)
                                                    with:[self myApiClient]];
    }];
}

Debugging LegacyViewControllerB's viewDidLoad, I expected to have the apiClient dependency already injected, but this is not the case. Why?

EDIT:

I have checked the sample application and I was wondering if there was a way to avoid knowing about the assembly and/or importing Typhoon in the ViewControllers. Actually I really liked the integration with storyboards because I was not making any reference to Typhoon.

So, let us say I don't have any storyboard, then the only way to get my ViewController injected would be to do the following?

MyApplicationAssembly *assembly = [[MyApplicationAssembly new] activate];
LegacyViewControllerB *legacyVCB = [assembly legacyVCB];
[self.navigationController pushViewController:legacyVCB animated:YES];

And had to modify my assembly to the following:

- (LegacyViewControllerB *)legacyVCB
{
    return [TyphoonDefinition withClass:[LegacyViewControllerB class]
                          configuration:^(TyphoonDefinition *definition) {
                              [definition useInitializer:@selector(initWithNibName:bundle:)
                                              parameters:^(TyphoonMethod *initializer) {
                                                  [initializer injectParameterWith:@"LegacyViewControllerB"];
                                                  [initializer injectParameterWith:[NSBundle mainBundle]];
                                              }];
                              [definition injectProperty:@selector(apiClient)
                                                    with:[self myApiClient]];
    }];
}

However this is not working for me either: [assembly legacyVCB] correctly returns an instance of LegacyViewControllerB with myApiClient injected, but when pushing it, LegacyViewControllerB's viewDidLoad does not have it injected. It seems that pushing it creates a new LegacyViewControllerB, because the memory address differs. Why do you think this is happening?

Thanks in advance.

1

1 Answers

0
votes

Typhoon hooks into UIStoryboard so that it works just like a regular storyboard with the added benefit that dependencies are injected, but as Typhoon is a dependency injection container, the normal way to obtain an injected instance is to ask Typhoon, via the assembly interface.

  • Inject the Assembly into a storyboard view controller that wants to present a non-storyboard controller.
  • Ask the assembly for a built instance.

Example:

UIViewController *controller = [assembly legacyVCB];
//Now push it into a container VC or subview

The Typhoon sample application shows lots of examples of this.