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
How to build own photo picker
Solution
import UIKit
import AVFoundation
import Photos
protocol 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 library
extension 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: UINavigationControllerDelegate
extension ImagePicker: UINavigationControllerDelegate { }
// MARK: UIImagePickerControllerDelegate
extension 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 UIKit
class 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: ImagePickerDelegate
extension 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 MobileCoreServices
class 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)
}
}