Reputation: 1759
I want to swizzle init init method of NSURLConnection class and i have tried this code but it doesn't seem to work for me
extension NSURLConnection{
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
let originalSelector = Selector("init:delegate:startImmediately:")
let swizzledSelector = Selector("my_init:delegate:startImmediately:")
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
// MARK: - Method Swizzling
func my_init(request: NSURLRequest, delegate: AnyObject?, startImmediately: Bool){
print("Inside Swizzled Method")
}
}
And here is the request which i am initiating from my view controller
let testPoint: String = "www.google.com"
guard let url = NSURL(string: testPoint) else {
print("Error: cannot create URL")
return
}
let urlRequest = NSURLRequest(URL: url)
let conn = NSURLConnection(request: urlRequest, delegate: self, startImmediately: true)
Upvotes: 0
Views: 1591
Reputation: 7944
I think there are two things that have to be fixed:
As mentioned in this answer, you should use Objective-C method signature in originalSelector
:
`let originalSelector = Selector("initWithRequest:delegate:startImmediately:")`
You don't return anything from my_init
method. You should return the same type as the method being swizzled, in this case NSURLConnection
.
func my_init(request: NSURLRequest, delegate: AnyObject?, startImmediately: Bool) -> NSURLConnection? {
print("Inside Swizzled Method")
//call the original initializer
return my_init( request, delegate: delegate, startImmediately: startImmediately)
}
You can see that my_init
is called in the swizzled method. In the runtime, it will call the original initWithRequest:delegate:startImmediately
as the methods will have been already swapped at this point.
Last but not least, NSURLConnection
is deprecated in iOS 9. It is highly recommended to use NSURLSession
instead, as it's more modern and has more useful features.
Upvotes: 0
Reputation: 1962
extension NSURLConnection{
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
if self !== NSURLConnection.self {
return
}
dispatch_once(&Static.token) {
let originalSelector = Selector("initWithRequest:delegate:startImmediately:")
let swizzledSelector = Selector("initWithTest:delegate:startImmediately:")
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
// MARK: - Method Swizzling
convenience init(test: NSURLRequest, delegate: AnyObject?, startImmediately: Bool){
print("Inside Swizzled Method")
self.init()
}
}
Upvotes: 2