I'm following Swift & the Objective-C Runtime, it works for normal methods.
I like to swizzle init method, from my understanding, init is like a class method. So I tried swizzling init as instance and class method. But it does not seem to work
I can make it work using Objective C, just wonder how to make it work in Swift
Excerpted from my gist
dispatch_once(&Static.token) {
let originalSelector = Selector("init:source:destination:")
let swizzledSelector = Selector("ftg_init:source:destination:")
let originalMethod = class_getClassMethod(self, originalSelector)
let swizzledMethod = class_getClassMethod(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);
}
}
When creating the selector for a method, you should base it off the Obj C method signature since swizzling is done using the Obj C runtime.
So the original selector should be
initWithIdentifier:source:destination:Now this gets a little weird, since your init method is defined so that the label on the first argument is required (by having
identifiertwice), the selector you want to use is actuallyftg_initWithIdentifier:source:destination:The only documentation I could find about it talk about the translation from Obj C to Swift but it looks like the reverse is happening from Swift to Obj C.
Next,
init...is an instance method so you'll need to make two changes. You need to changeclass_getClassMethodtoclass_getInstanceMethodand you need to removeclassfrom yourft_init...method.So when all is said and done, your code should look like this (which worked for me)