如何使用Swift为UIApplication添加混合方法?

时间:2016-06-27 09:05:07

标签: objective-c swift frameworks swizzling method-swizzling

我在下面有一个代码,试图将调配方法用于UIApplication方法。但这些方法没有被调用。与此同时,我尝试将此代码添加到框架或私有窗格中。

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")
}
}

1 个答案:

答案 0 :(得分:0)

我认为你应该在你的AppDelegate中实现这个混合方法,而不是UIApplication的扩展。因为你混淆了AppDelegate的方法而不是UIApplication的方法。

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")
}
}