【问题标题】:How to add swizzling method to UIApplication using Swift?如何使用 Swift 向 UIApplication 添加 swizzling 方法?
【发布时间】:2016-06-27 09:05:06
【问题描述】:

我在下面有一段代码,试图将 swizzling 方法用于 UIApplication 方法。但是方法没有被调用。同时,我正在尝试将此代码添加到框架或私有 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")
}
}

【问题讨论】:

  • 我的观点和题外话:不要使用 swizzling。
  • 通常情况下,您不必随意使用这些方法,您只需按照自己的方式实现它们
  • @HoaParis 我只是想将我的 Objective-c 代码转换为 swift,我曾经在 Objective-c 中执行此操作,但它在 swift 版本中不起作用
  • 你应该在 AppDelegate 类而不是 UIApplication 类上实现这个。我添加了一个答案来显示代码。

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


【解决方案1】:

我认为你应该在你的 AppDelegate 中实现这个 swizzling 方法,而不是作为 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")
}
}

【讨论】:

  • 但我将其添加到框架中,我不知道 appdelegate
  • UIApplication 类别的示例可以在此处的 OneSignal 代码中找到:github.com/OneSignal/OneSignal-iOS-SDK/blob/master/iOS_SDK/…
  • 他们使用的解决方案是搜索所有符合 UIApplicationDelegate 的类,并在这些类上使用方法。你必须在 Swift 中做同样的事情。
  • 我尝试了 UIApplicationDelegate 但也没有结果
  • @SoheilB.Marvasti 你最后找到解决方案了吗?
猜你喜欢
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多