Есть несколько вещей, которые могут вызвать проблемы:
- Сигнатуры методов разные.Исходная реализация не имеет параметра
error
, но является функцией выброса.Кроме того, в отличие от вашего метода swizzled, sendSynchronousRequest
принимает URLRequest
вместо NSURLRequest
. - Вы используете метод экземпляра и метод класса.Я не уверен, как (или если) это может быть сделано для работы.
sendSynchronousRequest
выставлен Swift как функция броска.Это работает, если ваша функция swizzled не помечена throws
, но функции броска не могут быть доступны ObjC и могут вызвать проблемы при swizzled.
Вот некоторый рабочий код для игровой площадки:
import Foundation
import ObjectiveC
extension NSURLConnection {
@objc static func swizzSendSynchronousRequest(_ request: URLRequest?, returning response: URLResponse?) -> Data? {
print("Inside Sync Swizzled Method")
print("------------\(String(describing: request))")
return Data()
}
}
let originalRequestSyncSelector = #selector(NSURLConnection.sendSynchronousRequest(_:returning:))
let swizzledRequestSyncSelector = #selector(NSURLConnection.swizzSendSynchronousRequest(_:returning:))
let originalSyncRequestMethod = class_getClassMethod(NSURLConnection.self, originalRequestSyncSelector)
let swizzledSyncRequestMethod = class_getClassMethod(NSURLConnection.self, swizzledRequestSyncSelector)
method_exchangeImplementations(originalSyncRequestMethod!, swizzledSyncRequestMethod!)
let request = URLRequest(url: URL(string: "https://example.com")!)
do {
let data = try NSURLConnection.sendSynchronousRequest(request, returning: nil)
print(data)
} catch {
print(error)
}
Несмотря на это, я думаю, что было бы лучше выполнить Swizzling в Objective-C. гораздо лучшая документация о том, как это сделать, и вы можете избежать ловушек в Swift <-> Objective-C магия мостов.