I have a continuous integration environment that builds up the iOS project out of Unity from scratch every time. I am trying to figure out a good way to hook some code into the applicationDidFinishLaunchingWithOptions for initializing some 3rd party plugins. Without keeping the project around on the build server and inserting our own subclass of UnityAppController, I am not finding a good solution.
Is there a good method of interjecting your own code into applicationDidFinishLaunching or similar iOS lifecycle events without subclassing, copying over your own appcontroller during postprocessbuildphase or manually having to manage the generated iOS project? Does anyone have experience trying to do something similar?
Yeah, that’s true. If you’re just initializing things though, you can use one of the other similar-but-not-implemented functions, like applicationWillFinishLaunching.
Or, if you really need to do it in applicationDidFinishLaunching, you can swizzle your own implementation in:
@implementation UnityAppController (YourCategoryForStuff)
+ (void)load {
Method original, swizzled;
original = class_getInstanceMethod(self, @selector(application:didFinishLaunchingWithOptions:));
swizzled = class_getInstanceMethod(self, @selector(customApplication:didFinishLaunchingWithOptions:));
method_exchangeImplementations(original, swizzled);
}
-(BOOL)customApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
// do whatever you need here
// looks like it's just calling itself, but the implementations were swapped so we're actually
// calling the original once we're done
[self customApplication:application didFinishLaunchingWithOptions:launchOptions];
}
@end
Then just put your category files in Plugins/iOS and let Unity import it into your project for you.
Load gets called automatically as soon as the class gets loaded (before init, even). By swizzling there, you ensure that your implementation will be in place before anything else calls the original method.
So I guess there’s a chance that another implementation of load() could be defined in the original class, and in that case we’re in the same boat as before.
In general I think load is rarely implemented, so you’re probably fine to use it. Though, that said, if you have multiple things trying to inject themselves into applicationDidFinishLaunching you’re going to run into issues eventually and have to sort them out yourself no matter what method you use.