Swift - UIImagePickerController - how to use it?
You're grabbing a UIImage
named UIImagePickerControllerOriginalImage
and there exists no such image. You're meant to grab the UIImage
with the key UIImagePickerControllerOriginalImage
from the editingInfo
dictionary:
let tempImage = editingInfo[UIImagePickerControllerOriginalImage] as! UIImage
Details
- Xcode 11.4.1 (11E503a), Swift 5.2
More
Solution
import UIKitimport AVFoundationimport Photosprotocol ImagePickerDelegate: class { func imagePicker(_ imagePicker: ImagePicker, grantedAccess: Bool, to sourceType: UIImagePickerController.SourceType) func imagePicker(_ imagePicker: ImagePicker, didSelect image: UIImage) func cancelButtonDidClick(on imageView: ImagePicker)}class ImagePicker: NSObject { private weak var controller: UIImagePickerController? weak var delegate: ImagePickerDelegate? = nil func dismiss() { controller?.dismiss(animated: true, completion: nil) } func present(parent viewController: UIViewController, sourceType: UIImagePickerController.SourceType) { let controller = UIImagePickerController() controller.delegate = self controller.sourceType = sourceType self.controller = controller DispatchQueue.main.async { viewController.present(controller, animated: true, completion: nil) } }}// MARK: Get access to camera or photo libraryextension ImagePicker { private func showAlert(targetName: String, completion: ((Bool) -> Void)?) { DispatchQueue.main.async { [weak self] in guard let self = self else { return } let alertVC = UIAlertController(title: "Access to the \(targetName)", message: "Please provide access to your \(targetName)", preferredStyle: .alert) alertVC.addAction(UIAlertAction(title: "Settings", style: .default, handler: { action in guard let settingsUrl = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(settingsUrl) else { completion?(false); return } UIApplication.shared.open(settingsUrl, options: [:]) { [weak self] _ in self?.showAlert(targetName: targetName, completion: completion) } })) alertVC.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in completion?(false) })) UIApplication.shared.windows.filter { $0.isKeyWindow }.first? .rootViewController?.present(alertVC, animated: true, completion: nil) } } func cameraAsscessRequest() { if delegate == nil { return } let source = UIImagePickerController.SourceType.camera if AVCaptureDevice.authorizationStatus(for: .video) == .authorized { delegate?.imagePicker(self, grantedAccess: true, to: source) } else { AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in guard let self = self else { return } if granted { self.delegate?.imagePicker(self, grantedAccess: granted, to: source) } else { self.showAlert(targetName: "camera") { self.delegate?.imagePicker(self, grantedAccess: $0, to: source) } } } } } func photoGalleryAsscessRequest() { PHPhotoLibrary.requestAuthorization { [weak self] result in guard let self = self else { return } let source = UIImagePickerController.SourceType.photoLibrary if result == .authorized { DispatchQueue.main.async { [weak self] in guard let self = self else { return } self.delegate?.imagePicker(self, grantedAccess: result == .authorized, to: source) } } else { self.showAlert(targetName: "photo gallery") { self.delegate?.imagePicker(self, grantedAccess: $0, to: source) } } } }}// MARK: UINavigationControllerDelegateextension ImagePicker: UINavigationControllerDelegate { }// MARK: UIImagePickerControllerDelegateextension ImagePicker: UIImagePickerControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[.editedImage] as? UIImage { delegate?.imagePicker(self, didSelect: image) return } if let image = info[.originalImage] as? UIImage { delegate?.imagePicker(self, didSelect: image) } else { print("Other source") } } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { delegate?.cancelButtonDidClick(on: self) }}
Full Usage
Info.plist
<key>NSPhotoLibraryUsageDescription</key> <string>bla-bla-bla</string> <key>NSCameraUsageDescription</key> <string>bla-bla-bla</string>
ViewController (do not forget to paste solution code)
import UIKitclass ViewController: UIViewController { private weak var imageView: UIImageView! private lazy var imagePicker: ImagePicker = { let imagePicker = ImagePicker() imagePicker.delegate = self return imagePicker }() override func viewDidLoad() { super.viewDidLoad() navigationItem.leftBarButtonItem = UIBarButtonItem(title: "camera", style: .plain, target: self, action: #selector(cameraButtonTapped)) navigationItem.rightBarButtonItem = UIBarButtonItem(title: "photo", style: .plain, target: self, action: #selector(photoButtonTapped)) let imageView = UIImageView(frame: CGRect(x: 40, y: 80, width: 200, height: 200)) imageView.backgroundColor = .lightGray view.addSubview(imageView) self.imageView = imageView } @objc func photoButtonTapped(_ sender: UIButton) { imagePicker.photoGalleryAsscessRequest() } @objc func cameraButtonTapped(_ sender: UIButton) { imagePicker.cameraAsscessRequest() }}// MARK: ImagePickerDelegateextension ViewController: ImagePickerDelegate { func imagePicker(_ imagePicker: ImagePicker, didSelect image: UIImage) { imageView.image = image imagePicker.dismiss() } func cancelButtonDidClick(on imageView: ImagePicker) { imagePicker.dismiss() } func imagePicker(_ imagePicker: ImagePicker, grantedAccess: Bool, to sourceType: UIImagePickerController.SourceType) { guard grantedAccess else { return } imagePicker.present(parent: self, sourceType: sourceType) }}
Images
import MobileCoreServicesclass SecondViewController: UIViewController,UINavigationControllerDelegate, UIImagePickerControllerDelegate { @IBOutlet var img:UIImageView!=nil override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } @IBAction func buttonTapped(AnyObject) { if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){ println("Button capture") var imag = UIImagePickerController() imag.delegate = self imag.sourceType = UIImagePickerControllerSourceType.PhotoLibrary; //imag.mediaTypes = [kUTTypeImage]; imag.allowsEditing = false self.presentViewController(imag, animated: true, completion: nil) } } func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) { let selectedImage : UIImage = image //var tempImage:UIImage = editingInfo[UIImagePickerControllerOriginalImage] as UIImage img.image=selectedImage self.dismissViewControllerAnimated(true, completion: nil) } }