1 Reply
      Latest reply: Feb 10, 2017 3:28 PM by eskimo RSS
      Dusty McMuffin Level 1 Level 1 (0 points)

        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?

        • Re: AppDelegate Class not Available to Obj-C Embedded Library in iOS Swift App
          eskimo Apple Staff Apple Staff (7,530 points)

          Let me start by saying that swizzling in production code is almost always a bad idea.  Rather than have your library swizzle app delegate methods, why not change your library’s interface so you get the control you need?

          Notwithstanding the above, it’s hard to offer any concrete advice about your current issue because there’s some key details missing.  You wrote:

          … the AppDelegate is null (or nil) when the library is initializing …

          and:

          Is there some difference in the order of initialization of the application delegate between the two languages?

          but didn’t give any details about how your library gets initialised.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"