Last active
June 8, 2020 09:00
-
-
Save ncreated/2e1f5ea592a6e861da46c2a56df79f1c to your computer and use it in GitHub Desktop.
Comparison of Object-Oriented vs Singleton-Based swizzlers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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