5

I'm trying to access both the camera and photo library in swift4 using the following code

let imagePickerController = UIImagePickerController()
    imagePickerController.delegate = self
    let alert = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
    alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
        imagePickerController.sourceType = .camera
        print(1)
    }))
    alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
        imagePickerController.sourceType = .photoLibrary
    }))
    alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
    self.present(alert, animated: true, completion: nil)

but it's not working. I'm not get an access authorization request even though I made sure that the plist has the camera and photo library authorization. I manipulate the code a bit to the following

AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in
    }
    let photos = PHPhotoLibrary.authorizationStatus()
    if photos == .notDetermined {
        PHPhotoLibrary.requestAuthorization({status in
        })
    }

    let imagePickerController = UIImagePickerController()
    imagePickerController.delegate = self
    let alert = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
    alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
        imagePickerController.sourceType = .camera
        print(1)
    }))
    alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
        imagePickerController.sourceType = .photoLibrary
    }))
    alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
    self.present(alert, animated: true, completion: nil)

Now I am getting the authorization request for both cameras and photo library and I can see the AlertView but when I press camera or Photo Album as shown in the picture nothing happens.

enter image description here

I tried on a device and simulator for the camera.

Sarabjit Singh
  • 1,814
  • 1
  • 17
  • 28
Ahmed
  • 1,229
  • 2
  • 20
  • 45
  • You can present the uiImagepickercontroller in alert action with particular source type camera and photolibrary or take permission code in this alert action – Virani Vivek Sep 19 '18 at 06:00
  • Can you elaborate more – Ahmed Sep 19 '18 at 06:03
  • Did you added **UINavigationControllerDelegate** ?? – Yash Bhikadiya Sep 19 '18 at 06:08
  • yup I added UINavigationControllerDelegate &&UIImagePickerControllerDelegate – Ahmed Sep 19 '18 at 06:09
  • you have to add **present(imagePickerController, animated: true, completion: nil)** after your source type. – Yash Bhikadiya Sep 19 '18 at 06:11
  • i did check the last line of the code – Ahmed Sep 19 '18 at 06:14
  • yes but that was for alert presentation.If you want to select images from camera of library you must have to present you imageController picker. – Yash Bhikadiya Sep 19 '18 at 06:15
  • it work only with the photo doesnot work with camera – Ahmed Sep 19 '18 at 06:17
  • check in device.Simulator not supported camera. – Yash Bhikadiya Sep 19 '18 at 06:18
  • That not correct you present the alert because there are two options. if you choose imagepicker controller you are just assiging it to photolibrary. You dont get the alertViewController if you do present(imagePickerController, animated: true, completion: nil) – Ahmed Sep 19 '18 at 06:19
  • you have to redirect after selection of camera or photoLibrary .so that time you must present your imagePicker .If you are not assign that then you can not redirect to Photos or Camera . So you have to present your ImagePickerController. Refer Link :: https://developer.apple.com/documentation/uikit/uiimagepickercontroller – Yash Bhikadiya Sep 19 '18 at 06:23
  • thanks I will check it. It is working now – Ahmed Sep 19 '18 at 06:31

2 Answers2

25

Here is the code to load image from photos & camera in iOS.

⁃ You need to create an outlet of your UIImageView

⁃ Then add a tap gesture on to image view

⁃ Then connect tap gesture with the didTapOnImageView function.

⁃ Then add the following extension to your view controller.

//MARK:- Image Picker
extension YourViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    //This is the tap gesture added on my UIImageView.
    @IBAction func didTapOnImageView(sender: UITapGestureRecognizer) {
        //call Alert function
        self.showAlert()
    }

    //Show alert to selected the media source type.
    private func showAlert() {

        let alert = UIAlertController(title: "Image Selection", message: "From where you want to pick this image?", preferredStyle: .actionSheet)
        alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
            self.getImage(fromSourceType: .camera)
        }))
        alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
            self.getImage(fromSourceType: .photoLibrary)
        }))
        alert.addAction(UIAlertAction(title: "Cancel", style: .destructive, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }

    //get image from source type
    private func getImage(fromSourceType sourceType: UIImagePickerController.SourceType) {

        //Check is source type available
        if UIImagePickerController.isSourceTypeAvailable(sourceType) {

            let imagePickerController = UIImagePickerController()
            imagePickerController.delegate = self
            imagePickerController.sourceType = sourceType
            self.present(imagePickerController, animated: true, completion: nil)
        }
    }

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

        self.dismiss(animated: true) { [weak self] in

            guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
            //Setting image to your image view
            self?.profileImgView.image = image
        }
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }

}

Note: Don't forget to add the privacy settings in info.plist

Privacy - Camera Usage Description

Privacy - Photo Library Usage Description

Naresh
  • 869
  • 8
  • 17
10

First of all, you need to import these libraries:

import Photos
import UIKit

 @IBOutlet weak var loadPhoto: UIButton!

And you need setup delegates:

class YourClass: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UNUserNotificationCenterDelegate 

func displayUploadImageDialog(btnSelected: UIButton) {
    let picker = UIImagePickerController()
    picker.delegate = self
    picker.allowsEditing = true
    let alertController = UIAlertController(title: "", message: "Upload profile photo?".localized(), preferredStyle: .actionSheet)
    let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: "Cancel action"), style: .cancel, handler: {(_ action: UIAlertAction) -> Void in
        alertController.dismiss(animated: true) {() -> Void in }
    })
    alertController.addAction(cancelAction)
    let cameraRollAction = UIAlertAction(title: NSLocalizedString("Open library".localized(), comment: "Open library action"), style: .default, handler: {(_ action: UIAlertAction) -> Void in
        if UI_USER_INTERFACE_IDIOM() == .pad {
            OperationQueue.main.addOperation({() -> Void in
                picker.sourceType = .photoLibrary
                self.present(picker, animated: true) {() -> Void in }
            })
        }
        else {
            picker.sourceType = .photoLibrary
            self.present(picker, animated: true) {() -> Void in }
        }
    })
    alertController.addAction(cameraRollAction)
    alertController.view.tintColor = .black
    present(alertController, animated: true) {() -> Void in }
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let image = info[UIImagePickerControllerOriginalImage] as! UIImage
    profileImage.image = image
    let imageData = UIImageJPEGRepresentation(image, 0.05)
    self.dismiss(animated: true, completion: nil)
}

func checkPermission() {
    let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
    switch authStatus {
    case .authorized:
        self.displayUploadImageDialog(btnSelected: self.loadPhoto)
    case .denied:
        print("Error")
    default:
        break
    }
}

func imagePickerControllerDidCancel(picker: UIImagePickerController) {
    self.dismiss(animated: true, completion: nil)
}

func checkLibrary() {
    let photos = PHPhotoLibrary.authorizationStatus()
    if photos == .authorized {
        switch photos {
        case .authorized:
            self.displayUploadImageDialog(btnSelected: self.loadPhoto)
        case .denied:
            print("Error")
        default:
            break
        }
    }
}

Setup action for button:

@IBAction func loadPhotoTapped(_ sender: UIButton) {
    let photos = PHPhotoLibrary.authorizationStatus()
    if photos == .notDetermined {
        PHPhotoLibrary.requestAuthorization({status in
            if status == .authorized{
                print("OKAY")
            } else {
                print("NOTOKAY")
            }
        })
    }
    checkLibrary()
    checkPermission()
}

At the Info.plist setup the permissions:

Privacy - Media Library Usage Description

Privacy - Photo Library Usage Description

Privacy - Camera Usage Description

This should work.

Community
  • 1
  • 1
qunzi
  • 175
  • 11