I have a library written in Objective C, published as a Cocoapod. Part of what the library does is some swizzling of the AppDelegate class of any app that it is added to. When the library is added to a simple Objective-C app (a single-page app with nothing in it), the callback methods are swizzled properly and everyone is happy. However, when the library is added to a similar Swift app, the swizzling fails because the AppDelegate is null (or nil) when the library is initializing (and swizzling is attempted).
Here is a peek at the code within the library:
UIResponder+MyCustomMethods.m
/*
* This class swizzles the methods needed to observe protocol methods
*/
@implementation UIResponder (WTAutomatics)
...
+ (void)swizzleAppDelegate:(SEL)original with:(SEL)replacement forProtocol:(Protocol *)protocol
{
id appDel = [[UIApplication sharedApplication] delegate];
Class appDelegate = [appDel class];
// Alternatively, we can do this. Both work the same.
// Class appDelegate = [[[UIApplication sharedApplication] delegate] class];
NSLog(@"Starting swizzle: %@", NSStringFromSelector(original));
if (!appDelegate) {
WTLog(@"Failed to swizzle because appDelegate is null.");
return;
}
if (class_conformsToProtocol(appDelegate, protocol)) {
// Do the method swizzling
...
}
}
In the code above, the value of appDelegate is valid and the swizzling works in any Objective C app. However, appDelegate is null when this is run within a Swift app and the swizzle fails.
Is there some difference in the order of initialization of the application delegate between the two languages? Is there something else I'm missing?