0

I really hope I'm not making a duplicate - but I read a ton different camera-questions inhere and implemented all of their answers, with the same result: Nothing happens!

No errors, the app doesn't crash, no problems whatsoever - only there is no sign of the camera, which should be activated! My goal is to get it activated in viewDidAppear or viewDidLoad, but I also tried testing it by connecting the code to a button - same result; nothing. Both on my own device and on the simulator: nothing!

What am i getting wrong in this simple code?? - Or which setting do I need to change? I have tried playing with the "data protection": nothing!

Code:

class CreateNewPerson: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

func viewDidAppear () {
    let imagePicker = UIImagePickerController()

    imagePicker.delegate = self
    imagePicker.sourceType = .camera
    present(imagePicker, animated: true, completion: nil)
}

private func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]!) {
    PersonPhoto.image = info[UIImagePickerControllerOriginalImage] as? UIImage
    dismiss(animated: true, completion: nil)
}

Hope someone can help me!

Photo of info.plist (where I can't seem to find the camera ussage description) - maybe I'm an idiot...: enter image description here

Thanks!

Scriptable
  • 19,402
  • 5
  • 56
  • 72
Anton Bjerg
  • 85
  • 2
  • 9
  • Unrelated… but always call `super.viewDidAppear()` – Ashley Mills Oct 24 '18 at 08:54
  • Alright - will do! Thanks for the note ;) - I tried finding the camera usage description? But where should it be?? I can't seem to find it anywhere? – Anton Bjerg Oct 24 '18 at 08:57
  • And I know, I won't see it on the simulator - but nothing happens on my own device either – Anton Bjerg Oct 24 '18 at 08:57
  • in the info.plist you should have a listing under 'Privacy - Camera Usage Description ' – Scriptable Oct 24 '18 at 08:59
  • I don't have that - should I upload a photo of my info.plist to show you? Only thing I can find is under settings --> Capabilities --> Data Protection (which could have something to do with the users photos...) - but nothing happens when I flip it on or off! :D – Anton Bjerg Oct 24 '18 at 09:01
  • No you dont need to show your info.plist. but to use the camera, location, photo library, contacts and some others you MUST provide a usage description in the plist for each one you use. If you dont... it wont work. – Scriptable Oct 24 '18 at 09:03
  • Add this key to your plist along with the other ones: "Privacy - Camera Usage Description" of type String. The value is optional – Alan S Oct 24 '18 at 09:05
  • Possible duplicate of [NSCameraUsageDescription in iOS 10.0 runtime crash?](https://stackoverflow.com/questions/39465687/nscamerausagedescription-in-ios-10-0-runtime-crash) – Scriptable Oct 24 '18 at 09:05
  • haha - see .. I knew I was an idiot! Never knew that I could add anything to my info.plist!! Thanks a lot! I'll just try and run it on my device to check if it works! – Anton Bjerg Oct 24 '18 at 09:07
  • @Scriptable - I still get nothing! I added this to my info.plist and ran it on my device: nothing ... – Anton Bjerg Oct 24 '18 at 09:11
  • @AntonBjerg, most probably your view is not in window hierarchy. please check the logs in console. – Vinaykrishnan Oct 24 '18 at 09:12
  • It says a lot of stuff in the console.. It could be that, yeah! How do I change that? And to what excactly? – Anton Bjerg Oct 24 '18 at 09:15
  • https://stackoverflow.com/q/15287678/2323806, might help – Vinaykrishnan Oct 24 '18 at 09:16
  • You need to manage permissions, the app needs to be granted permission to use the camera. the description you added to the plist is the text that is shown when prompted for permission. – Scriptable Oct 24 '18 at 09:21
  • I'm not so sure this is it though... The warning: "...whose view is not in the window hierarchy...", which everyone with this problem seem to be referring to - it doesn't say that in the console – Anton Bjerg Oct 24 '18 at 09:24
  • Ohk, try adding some delay. self.perform(#selector(ViewController.openImagePicker), with: self, afterDelay: 2.0) openImagePicker : contains the code to open image picker. – Vinaykrishnan Oct 24 '18 at 09:31
  • @Vinaykrishnan please do _not_ give this awful advice. Instead, find out _why_ the view isn't in the hierarchy, and then make the call at the appropriate time. – Ashley Mills Oct 24 '18 at 09:44
  • @AshleyMills, it's just a tip to get near to the exact problem,It might happen if the view is not completely loaded yet. doesn't mean that it should work. – Vinaykrishnan Oct 24 '18 at 09:51
  • _"It might happen if the view is not completely loaded yet"_ - what does that even mean? He's calling his camera code in `viewDidAppear`. Please enlighten us. – Ashley Mills Oct 24 '18 at 09:53
  • @AshleyMills, hope this could help https://stackoverflow.com/a/10151385/2323806 – Vinaykrishnan Oct 24 '18 at 09:54

2 Answers2

3

You need to add a Camara usage description into your info.plist file and ask permission for your app to access the camera.

Add this to your plist file:

Privacy - Camera Usage Description

With some text like

"We need your permission to access the device camera"

To request permission:

AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in
    if granted {
        // show the image picker 
    } else {
        // show an error 
    }
}

It is usually best to check if you need permission or what state the permissions are in, so I would do it like this...

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated) 

    checkCameraPermissions() 
}

private func checkCameraPermissions() {
    let status = AVCaptureDevice.authorizationStatus(for: .video)
    switch status {
       case .authorized: 
          self.presentPicker()
       case .notDetermined:
           self.requestPermissions()
       case .denied:
          // user denied access
          self.permissionDenied()   
    }
}

private func requestAccess() {
    AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in
        if !granted {
            // show an error 
        }
        // call it again in to recheck now that permissions have changed.
        checkCameraPermissions
    }
}

private func presentPicker() {
    // permissions are all set, continue as planned.
}

private func permissionDenied() {
    // show an alert and link to app settings to turn on

    // usually I would show a view which explains they have denied permission to the camera so this functionality isn't available until they manually change the setting in the app settings.
}
Scriptable
  • 19,402
  • 5
  • 56
  • 72
0

You have to add CreateNewPerson in UINavigationController after that run your code.

Don't forget to add Privacy - Camera Usage Description in info.plist

Tak Rahul
  • 176
  • 7