Kevin DiTraglia Kevin DiTraglia - 7 months ago 39
Swift Question

Implement protocol through extension

I'm trying to create a protocol that wraps the process of using the UIImagePickerController to make it more stream-lined in my apps. I essentially have something like this:

public protocol MediaAccessor : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func mediaCaptured(title: String, fileData: NSData, fileType: String)
}


and an extension that does all the heavy lifting of requesting the permission and handling the delegate methods:

public extension MediaAccessor where Self : UIViewController {
public func captureMedia() {
//All sorts of checks for picker authorization
let picker = UIImagePickerController()
picker.delegate = self
self.presentViewController(picker, animated: true, completion: nil)
}

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
//implementation of the delegate in extension
//even though everything compiles, this method is not called on picker completion
}
}


So everything compiles, but implementing the UIImagePickerControllerDelegate through the extension doesn't seem to register. When I show the picker, it allows me to take a picture, but the didFinishPickingImage call never happens. If I move that call directly into the controller everything works fine, but the idea of this was to hide this stuff from the view controller for a very clean interface into allowing a controller to access media from the device. Is implementing protocol methods through an extension like this something that can't work? Is there something I can change to allow this to work, without having to implement the protocol directly in my view controller?

Answer

Cocoa is written in Objective-C. Objective-C can't see Swift protocol extension code. So it's unaware of that implementation of imagePickerController:didFinishPickingImage:. If you want a delegate method to be called by Cocoa, you need to put it where Cocoa can see it.