Search code examples
swiftswift-extensionsswift-protocols

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?


Solution

  • 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.