Я использую абсолютно одинаковый подход для переключения двух AppDelegate
методов экземпляра - универсальных ссылок и ссылок на схемы URL. Я должен отметить, что обе тестовые ссылки правильно настроены. Я попытался проверить, как этот подход работает на iOS 12 и 13, и получил то же неожиданное поведение.
В случае, когда я пытаюсь кликнуть по универсальной ссылке, все работает как положено. В случае, когда я пытаюсь сделать то же самое со ссылкой на схему URL, я вижу, что успешно запущенный метод application(_:open:options:)
не запускается системой.
Если я инициализирую два пустых метода application(_:open:options:)
и application(_:continue:restorationHandler:)
в классе AppDelegate
и затем вызову method_exchangeImplementations
из моего кода ниже, я получаю успешно измененную реализацию методов application(_:open:options:)
и application(_:continue:restorationHandler:)
. Когда я пытаюсь выполнить щелчок по универсальной ссылке или по ссылке схемы URL в обоих случаях, я получаю ожидаемое поведение - система запускает мои извращенные методы.
Когда я не инициализирую пустые методы application(_:open:options:)
и application(_:continue:restorationHandler:)
в классе AppDelegate
, как вы можете видеть из моего кода ниже, я вызываю метод class_addMethod
для добавления реализации на лету к AppDelegate
экземпляр. В этом случае я вижу, что оба метода application(_:open:options:)
и application(_:continue:restorationHandler:)
успешно добавлены к экземпляру AppDelegate
, но когда я пытаюсь выполнить щелчок по ссылке на схему URL - система не запустила мой метод swizzled application(_:open:options:)
и т. наоборот с методом application(_:continue:restorationHandler:)
- щелчок по универсальной ссылке вызвал у меня метод swizzle.
// MARK: Swizzle AppDelegate universal links method.
private func swizzleContinueRestorationHandler() {
guard let swizzleMethod = class_getInstanceMethod(Swizzler.self, #selector(self.application(_:continue:restorationHandler:))) else { return }
let delegateClass: AnyClass! = object_getClass(UIApplication.shared.delegate)
let applicationSelector = #selector(UIApplicationDelegate.application(_:continue:restorationHandler:))
if let originalMethod = class_getInstanceMethod(delegateClass, applicationSelector) {
method_exchangeImplementations(originalMethod, swizzleMethod)
} else {
class_addMethod(delegateClass, applicationSelector, method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod))
}
}
// MARK: Swizzle AppDelegate URL schemes method.
private func swizzleOpenOptions() {
guard let swizzleMethod = class_getInstanceMethod(Swizzler.self, #selector(self.application(_:open:options:))) else { return }
let delegateClass: AnyClass! = object_getClass(UIApplication.shared.delegate)
let applicationSelector = #selector(UIApplicationDelegate.application(_:open:options:))
if let originalMethod = class_getInstanceMethod(delegateClass, applicationSelector) {
method_exchangeImplementations(originalMethod, swizzleMethod)
} else {
class_addMethod(delegateClass, applicationSelector, method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod))
}
}
// MARK: Swizzled AppDelegate universal links method.
@objc func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
...
}
// MARK: Swizzled AppDelegate URL schemes method.
@objc func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
...
}
Почему это происходит и как добавить метод application(_:open:options:)
на лету к экземпляру AppDelegate
и получить ожидаемое поведение послепереход по ссылке на схему URL?