I'm trying to inject a protocol extension initializer into an existing class's designated initializer. I don't think there's a way around it without overriding the designated initializer from the class, then call the protocol extension initializer within.
Below is what I'm trying, specifically with the UIViewController
class:
class FirstViewController: UIViewController, MyProtocol {
var locationManager: CLLocationManager?
var lastRendered: NSDate?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// TODO: How to call MyProtocol initializer?
// (self as MyProtocol).init(aDecoder) // Didn't compile
}
}
protocol MyProtocol: CLLocationManagerDelegate {
var locationManager: CLLocationManager? { get set }
var lastRendered: NSDate? { get set }
init?(coder aDecoder: NSCoder)
}
extension MyProtocol where Self: UIViewController {
// Possible to inject this into initialization process?
init?(coder aDecoder: NSCoder) {
self.init(coder: aDecoder)
setupLocationManager()
}
func setupLocationManager() {
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager?.distanceFilter = 1000.0
locationManager?.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// TODO
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
// TODO
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
// TODO
}
}
Is there a way to make use of protocol extensions initializers so it gets called automatically during the framework's existing initialization process?
You don't need to call a different initializer; you're already initializing. Moreover, you don't need to cast
self
to MyProtocol; you've already declared that it adopt MyProtocol. Plus, you've already injected MyProtocol'ssetupLocationManager
into FirstViewController, because your FirstViewController already adopts MyProtocol and the extension on MyProtocol is aimed at UIViewController, the superclass of FirstViewController.So, the method is already injected; now just go right ahead and call the injected method right there in the initializer you're already running. The following pared-down version of your code compiles perfectly well: