I am configuring the Initial Assemblies in the plist, which are used to instantiate the first controller in the storyboard.
later in the app i am changing the root view controller using:
TyphoonStoryboard* storyboard = [TyphoonStoryboard storyboardWithName:storyboardType factory:factory bundle:nil];
UIViewController* newRootView = [storyboard instantiateViewControllerWithIdentifier:identifier];
self.window.rootViewController = newRootView;
I would like to use the same assemblies when instantiating the new view controller. The reason is that i want the Singletons to remain Singletons. If the assemblies/factory changes all classes are created again, including singletons.
How can i get the factory used to initialize the first view controller in the storyboard?
Tight Storyboard Integration:
As long as plist integration is used, along with the usual UILaunchStoryboardName
and UIMainStoryboardFile
, then Typhoon will ensure that any Storyboard is a TyphoonStoryboard. Use exactly as with a normal storyboard, with the added benefit that dependencies will be injected according to the definitions in your TyphoonAssembly classes.
The TyphoonComponentFactory will be retained by the storyboard and so will persist throughout the lifecycle of your app.
Outside of Storyboards: (ie MacOS apps, utilities, etc)
The TyphoonComopnentFactory is indeed designed to be retained throughout the full life-cycle of your app. (Although you could do something else if you wished).
Key concept:
TyphoonComponentFactory
as is.There are two ways to retain the TyphoonComponentFactory when proceeding from one object-graph to another. We call this making of your components 'Typhoon aware'.
Approach 1: Inject the assembly:
- (MyAppDelegate *)appDelegate
{
return [TyphoonDefinition withClass:[MyAppDelegate class]
configuration:^(TyphoonDefinition *definition)
{
//Other injections . . .
[definition injectProperty:@selector(factory) with:self];
}];
}
The above example injects the TyphoonComponentFactory
into a property called factory
.
TyphoonComponentFactory
.components
of type CoreCompopnents
and inject the assembly as that.More info on this feature can be found in the User Guide here.
Approach 2: Use callback hook:
Another way of making a component 'Typhoon aware' is to use Typhoon's callback hooks. by overriding NSObject category methods:
typhoonSetFactory:(id)thefactory
As with the other approach above, the factory can be used as a TyphoonComponentFactory
or any of your assembly interfaces my pose in front, both of the following are fine:
typohoonSetFactory:(TyphoonComponentFactory*)factory
{
//Do something with factory
}
typhoonSetFactory:(ApplicationAssembly*)assembly
{
//Do something with assembly
}
Of the two approaches, use the one that suits you best. We recommend the former, as it 'non-invasive' meaning your own classes don't directly call any Typhoon APIs. If you ever wished to migrate away from Typhoon, you would simply provide an alternative implementation of the assembly.
Proceeding from one object graph to another:
Once a component is 'Typhoon aware' using either of the above methods, we can use this to proceed from one object graph to another.
TyphoonScopeObjectGraph
, meaning you can load a view controller, including any delegates and circular references. Upon completion, it will be discarded from memory.TyphoonScopeSingleton
(or TyphoonScopeWeakSingleton
) will be retained.More information on this feature is in the User Guide here.
Proceeding from one story board to another:
To programmatically instantiate a new storyboard at some point in your app (eg a view controller):
UIStoryboard *board = [TyphoonStoryboard storyboardWithName:@"name"
factory:factory bundle:[NSBundle mainBundle]];
. . obtain the factory using Approach 1 or Approach 2 above.
Summary: