Skip to content

Instantly share code, notes, and snippets.

@rpassis
Last active August 27, 2019 10:40
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpassis/4622291029cd12e4ce2b7585d3e62d15 to your computer and use it in GitHub Desktop.
Save rpassis/4622291029cd12e4ce2b7585d3e62d15 to your computer and use it in GitHub Desktop.
Protocol and extension for handling the presentation of image picker controllers and selection of media
// Since we are unable to extend ObjC protocols in swift, we wrap this around a custom NSObject subclass
// that deals exclusive with handling the image picker delegate methods and chaining the response down to
// the MediaPickerPresenter conforming delegate
class ImagePickerHandler: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var delegate: MediaPickerPresenter?
let sourceType: UIImagePickerControllerSourceType
let picker = UIImagePickerController()
init(sourceType: UIImagePickerControllerSourceType) {
self.sourceType = sourceType
super.init()
self.picker.delegate = self
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let mediaType = info[UIImagePickerControllerMediaType] as? String {
switch mediaType {
case String(kUTTypeImage):
if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.delegate?.didSelectFromMediaPicker(withImage: selectedImage)
}
case String(kUTTypeImage), String(kUTTypeMovie), String(kUTTypeVideo):
if let selectedMediaURL = info[UIImagePickerControllerMediaURL] as? NSURL {
self.delegate?.didSelectFromMediaPicker(withMediaUrl: selectedMediaURL)
}
default:
break
}
}
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
protocol MediaPickerPresenter {
var imagePickerHandler: ImagePickerHandler { get set }
func presentMediaPicker(fromController controller: UIViewController, sourceType: UIImagePickerControllerSourceType)
func didSelectFromMediaPicker(withImage image: UIImage)
func didSelectFromMediaPicker(withMediaUrl mediaUrl: NSURL)
}
extension MediaPickerPresenter {
func presentMediaPicker(fromController controller: UIViewController, sourceType: UIImagePickerControllerSourceType) {
imagePickerHandler.delegate = self
controller.present(imagePickerHandler.picker, animated: true, completion: nil)
}
}
class PresenterViewController: UIViewController, MediaPickerPresenter {
var imagePickerHandler = ImagePickerHandler(sourceType: .photoLibrary)
func presentPicker() {
self.presentMediaPicker(fromController: self)
}
func didSelectFromMediaPicker(withImage image: UIImage) {
// ...
}
func didSelectFromMediaPicker(withMediaUrl mediaUrl: NSURL) {
// ...
}
}
@zjfjack
Copy link

zjfjack commented Mar 23, 2018

Thanks, a good solution to solve the problem.

@crgg
Copy link

crgg commented Dec 28, 2018

Hi, good solution, but don't assign type sourceType.

@experion-tibin
Copy link

Hi, good solution, but don't assign type sourceType.

Could you explain why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment