Skip to content

Instantly share code, notes, and snippets.

@ncreated
Last active June 8, 2020 09:00
Show Gist options
  • Save ncreated/2e1f5ea592a6e861da46c2a56df79f1c to your computer and use it in GitHub Desktop.
Save ncreated/2e1f5ea592a6e861da46c2a56df79f1c to your computer and use it in GitHub Desktop.
Comparison of Object-Oriented vs Singleton-Based swizzlers.
// MARK: - UIViewController.viewDidLoad() swizzling
class ViewDidLoadSwizzler: MethodSwizzler<
@convention(c) (UIViewController, Selector) -> Void, // <- Swizzle from
@convention(block) (UIViewController) -> Void // <- Swizzle to
> {
init() throws {
try super.init(selector: #selector(UIViewController.viewDidLoad), inClass: UIViewController.self)
}
}
let viewDidLoad = try ViewDidLoadSwizzler()
viewDidLoad.setNewImplementation { `self` in
print("viewDidLoad() was called")
viewDidLoad.originalImplementation(`self`, viewDidLoad.source.selector)
}
// MARK: - UIViewController.viewWillAppear() swizzling
class ViewWillAppear: MethodSwizzler<
@convention(c) (UIViewController, Selector, Bool) -> Void, // <- Swizzle from
@convention(block) (UIViewController, Bool) -> Void // <- Swizzle to
> {
init() throws {
try super.init(selector: #selector(UIViewController.viewWillAppear(_:)), inClass: UIViewController.self)
}
}
let viewWillAppear = try ViewWillAppear()
viewWillAppear.setNewImplementation { `self`, animated in
print("viewWillAppear(\(animated)) was called")
viewWillAppear.originalImplementation(`self`, viewWillAppear.source.selector, animated)
}
// MARK: - UIViewController.viewDidAppear() swizzling
class ViewDidAppear: MethodSwizzler<
@convention(c) (UIViewController, Selector, Bool) -> Void, // <- Swizzle from
@convention(block) (UIViewController, Bool) -> Void // <- Swizzle to
> {
init() throws {
try super.init(selector: #selector(UIViewController.viewDidAppear), inClass: UIViewController.self)
}
}
let viewDidAppear = try ViewDidAppear()
viewDidAppear.setNewImplementation { `self`, animated in
print("viewDidAppear(\(animated)) was called")
viewDidAppear.originalImplementation(`self`, viewDidAppear.source.selector, animated)
}
// MARK: - UIViewController.viewDidLoad() swizzling
private struct ViewDidLoad {
private typealias TypedIMP = @convention(c) (UIViewController, Selector) -> Void
private typealias TypedBlockIMP = @convention(block) (UIViewController) -> Void
private static let selector = #selector(UIViewController.viewDidLoad)
let method: MethodSwizzler.FoundMethod
init() throws {
guard let foundMethod = swizzler.findMethodRecursively(with: Self.selector, in: UIViewController.self) else {
throw MethodSwizzlerException("Selector \(selector) not found on `UIViewController.self`")
}
self.method = foundMethod
}
func swizzle() {
swizzler.swizzle(method, impSignature: TypedIMP.self) { currentTypedImp -> IMP in
let newImpBlock: TypedBlockIMP = { impSelf in
print("viewDidLoad() was called")
return currentTypedImp(impSelf, Self.selector)
}
return imp_implementationWithBlock(newImpBlock)
}
}
}
let viewDidLoad = try ViewDidLoad()
viewDidLoad.swizzle()
// MARK: - UIViewController.viewWillAppear() swizzling
private struct ViewWillAppear {
private typealias TypedIMP = @convention(c) (UIViewController, Selector, Bool) -> Void
private typealias TypedBlockIMP = @convention(block) (UIViewController, Bool) -> Void
private static let selector = #selector(UIViewController.viewWillAppear)
let method: MethodSwizzler.FoundMethod
init() throws {
guard let foundMethod = swizzler.findMethodRecursively(with: Self.selector, in: UIViewController.self) else {
throw MethodSwizzlerException("Selector \(selector) not found on `UIViewController.self`")
}
self.method = foundMethod
}
func swizzle() {
swizzler.swizzle(method, impSignature: TypedIMP.self) { currentTypedImp -> IMP in
let newImpBlock: TypedBlockIMP = { impSelf, animated in
print("viewWillAppear() was called")
return currentTypedImp(impSelf, Self.selector, animated)
}
return imp_implementationWithBlock(newImpBlock)
}
}
}
let viewWillAppear = try ViewWillAppear()
viewWillAppear.swizzle()
// MARK: - UIViewController.viewDidAppear() swizzling
private struct ViewDidAppear {
private typealias TypedIMP = @convention(c) (UIViewController, Selector, Bool) -> Void
private typealias TypedBlockIMP = @convention(block) (UIViewController, Bool) -> Void
private static let selector = #selector(UIViewController.viewDidAppear)
let method: MethodSwizzler.FoundMethod
init() throws {
guard let foundMethod = swizzler.findMethodRecursively(with: Self.selector, in: UIViewController.self) else {
throw MethodSwizzlerException("Selector \(selector) not found on `UIViewController.self`")
}
self.method = foundMethod
}
func swizzle() {
swizzler.swizzle(method, impSignature: TypedIMP.self) { currentTypedImp -> IMP in
let newImpBlock: TypedBlockIMP = { impSelf, animated in
print("viewDidAppear() was called")
return currentTypedImp(impSelf, Self.selector, animated)
}
return imp_implementationWithBlock(newImpBlock)
}
}
}
let viewDidAppear = try ViewDidAppear()
viewDidAppear.swizzle()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment