Roobaan M T
4 min readMar 29, 2023

How to pick and capture an image using swift with UIImagePickerController?

I had faced to pick and capture image from mobile for my project. I explained below how to pick a image from the mobile from zero to required.

I have also attached my github project at the end of the article. Please refer it

Lets jump in to the topic…..

Photo by Franck on Unsplash
  1. Permission Description

In iOS to access camera and photos we need to give the permission description in the Info property file in project. Remember that you should have to give the detailed description about the permission you are asking. In some cases Apple might reject your app approval on App store.

$(PRODUCT_MODULE_NAME) is nothing but your project name.

This is where the permission description shows while asking for permission

2. Alert action

Use the below code to choose whether to open camera or photos. This will pop up alert to open camera or photos.

    // it shows the alert to choose the type to pick or capture image from mobile
func showImagePickerAlert(controller: UIViewController, completionHandler: @escaping (UIImage?) -> Void) {
self.viewController = controller
self.completionHandler = completionHandler
let alertController = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)

if UIImagePickerController.isSourceTypeAvailable(.camera) {
let cameraAction = UIAlertAction(title: "Take Photo", style: .default) { (_) in
self.checkCameraPermission()
}
alertController.addAction(cameraAction)
}

let galleryAction = UIAlertAction(title: "Choose From Gallery", style: .default) { (_) in
self.checkPhotoLibraryPermission()

}
alertController.addAction(galleryAction)

let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
viewController?.present(alertController, animated: true, completion: nil)
}

3. To check and ask permission.

Below code will check permission for the camera and photos. If the permissions were not determined it will show a alert to grant the permission or not.

    
// to check the permisssion status of the camera
func checkCameraPermission() {

let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)

switch cameraAuthorizationStatus {
case .notDetermined: self.requestCameraPermission()
case .authorized: self.openCamera()
case .restricted, .denied: self.alertAccessNeeded(access: "Camera")
default:
break
}
}

// to check the permisssion status of the photo library
func checkPhotoLibraryPermission() {
let photolibraryAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
switch photolibraryAuthorizationStatus{
case .notDetermined:
PHPhotoLibrary.requestAuthorization({ (status) in
if status == PHAuthorizationStatus.authorized{
// photo library access given
self.openGallery()
}
})
case .authorized:
self.openGallery()

case .denied, .restricted:
self.alertAccessNeeded(access: "Photos")

default:
break
}
}

// request permission from user to access camera
func requestCameraPermission() {
AVCaptureDevice.requestAccess(for: .video, completionHandler: {accessGranted in

guard accessGranted == true else { return }
DispatchQueue.main.async {
self.openCamera() }
})
}

// if the access is denied before, this function will make navigate to settings to enable permission
func alertAccessNeeded(access: String) {
let settingsAppURL = URL(string: UIApplication.openSettingsURLString)!

let alert = UIAlertController(
title: "Need \(access) Access",
message: "\(access) access is required to make full use of this app.",
preferredStyle: UIAlertController.Style.alert
)

alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Allow \(access)", style: .cancel, handler: { (alert) -> Void in
UIApplication.shared.open(settingsAppURL, options: [:], completionHandler: nil)
}))

viewController?.present(alert, animated: true, completion: nil)
}

4. To open camera and photo library

Below code will used to open camera and photo library.

    
//it opens the camera in the mobile
func openCamera() {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.allowsEditing = true // it helps to edit the photo that choosen from mobile
viewController?.present(imagePicker, animated: true, completion: nil)
}
}

//it displays the photo library of your mobile
func openGallery() {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
DispatchQueue.main.async { [self] in

imagePicker.delegate = self

imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
viewController?.present(imagePicker, animated: true, completion: nil)
}}
}

4. Delegate functions

And this is the final stage…

Don’t forget to add the delegate function of UIImagePickerControllerDelegate to your class. Through this delegate function we get the selected / edited image and pass through the completionhandler to get into the viewcontroller.

    
// MARK: - UIImagePickerControllerDelegate
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

// if let assetURL = info [UIImagePickerController.InfoKey.referenceURL] as? URL {
// let result = PHAsset.fetchAssets(withALAssetURLs: [assetURL], options: nil)
// let asset = result.firstObject
// print(assetURL)
// print(result)
// print()
//
// }

var selectedImage: UIImage?
if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
selectedImage = image
} else if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
selectedImage = image
}
completionHandler?(selectedImage)
viewController?.dismiss(animated: true, completion: nil)
}

// delegate function will trigger when the user cancel the action
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("cancel")
completionHandler?(nil)
viewController?.dismiss(animated: true, completion: nil)
}

Make sure to assign the property in the class…

static let shared = ImagePickerHelper()    // instance of the class

var viewController: UIViewController?
var imagePicker = UIImagePickerController()
var completionHandler: ((UIImage?) -> Void)?

5. ImagePicker

To call the common class that we were created for image picker, use the below code

ImagePickerHelper.shared.showImagePickerAlert(controller : self, completionHandler: { [weak self] (image) in
guard let imagePic = image else{return}
DispatchQueue.main.async {
self?.profileImage.image = imagePic //image --> is the picked image
// here you can customize the code as you want
}
} )

For full project please visit my github project

That’s it. It worked!

Thanks for reading,

I hope you enjoyed it and feel free to add any comments for suggestions and more questions on this topic.

Happy coding!