0

I have a code below trying to use swizzling method to UIApplication methods. But the methods not getting called. Meanwhile, I'm trying to add this code into a framework or a private pod.

extension UIApplication {
public override class func initialize() {
    struct Static {
        static var token: dispatch_once_t = 0
    }

    struct SwizzlingSelector {
        let original:Selector
        let swizzled:Selector
    }

    // make sure this isn't a subclass
    if self !== UIApplication.self {
        return
    }

    dispatch_once(&Static.token) {
        let selectors = [
            SwizzlingSelector(
                original: Selector("application:didFinishLaunchingWithOptions:"),
                swizzled: Selector("custome_application:didFinishLaunchingWithOptions:")
            ),
            SwizzlingSelector(
                original: Selector("applicationDidEnterBackground:"),
                swizzled: Selector("custom_applicationDidEnterBackground:")
            )
        ]

        for selector in selectors {
            let originalMethod = class_getInstanceMethod(self, selector.original)
            let swizzledMethod = class_getInstanceMethod(self, selector.swizzled)

            let didAddMethod = class_addMethod(self, selector.original, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

            if didAddMethod {
                class_replaceMethod(self, selector.swizzled, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        }
    }
}

// MARK: - Method Swizzling
public func custome_application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
    print("is here")
    return true
}

func custom_applicationDidEnterBackground(application: UIApplication) {
    print("is herer")
}
}
Soheil
  • 5,054
  • 3
  • 24
  • 43
  • My opinion and off topic: Don't use swizzling. – dasdom Jun 27 '16 at 09:07
  • Normally, you don't have to swizzling to those methods, you just have to implement them your ways – Duyen-Hoa Jun 27 '16 at 09:07
  • @HoaParis Im just trying to convert my objective-c codes to swift and I used to do this in objective-c but it doesnt work in swift version – Soheil Jun 27 '16 at 09:33
  • You should implement this on AppDelegate class but not UIApplication class. I've added an answer to show the code. – Duyen-Hoa Jun 27 '16 at 09:50

1 Answers1

0

I think you should implement this swizzling method in your AppDelegate but not as extension of UIApplication. Cause you swizzle your AppDelegate's methods but not UIApplication's methods.

extension YourAppDelegate {
public override class func initialize() {
    struct Static {
        static var token: dispatch_once_t = 0
    }

    struct SwizzlingSelector {
        let original:Selector
        let swizzled:Selector
    }

    // make sure this isn't a subclass
    if self !== YourAppDelegate.self {
        return
    }

    dispatch_once(&Static.token) {
        let selectors = [
            SwizzlingSelector(
                original: Selector("application:didFinishLaunchingWithOptions:"),
                swizzled: Selector("custome_application:didFinishLaunchingWithOptions:")
            ),
            SwizzlingSelector(
                original: Selector("applicationDidEnterBackground:"),
                swizzled: Selector("custom_applicationDidEnterBackground:")
            )
        ]

        for selector in selectors {
            let originalMethod = class_getInstanceMethod(self, selector.original)
            let swizzledMethod = class_getInstanceMethod(self, selector.swizzled)

            let didAddMethod = class_addMethod(self, selector.original, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

            if didAddMethod {
                class_replaceMethod(self, selector.swizzled, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        }
    }
}

// MARK: - Method Swizzling
public func custome_application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
    print("is here")
    return true
}

func custom_applicationDidEnterBackground(application: UIApplication) {
    print("is herer")
}
}
Duyen-Hoa
  • 15,384
  • 5
  • 35
  • 44
  • But I'm adding this into a framework, I wouldn't know the appdelegate – Soheil Jun 27 '16 at 09:51
  • 1
    An example of UIApplication category can be found in OneSignal codes in here: https://github.com/OneSignal/OneSignal-iOS-SDK/blob/master/iOS_SDK/OneSignal/OneSignal.m – Soheil Jun 27 '16 at 10:26
  • 1
    The solution they use is to search for all classe that are conformed to UIApplicationDelegate and use methods swizzling on those classes. You will have to do the same way in Swift. – Duyen-Hoa Jun 27 '16 at 10:33
  • I tried with UIApplicationDelegate but no result either – Soheil Jun 27 '16 at 10:38
  • @SoheilB.Marvasti did you find any solutions in th end? – Shams Ahmed Sep 20 '16 at 09:08