Swift iOS -UIImagePicker's Photo Library Is Presented On Simulator But Crashes (won't present) On Actual Device While Running Xcode

I’m on Swift 3, iOS 10.3, and Xcode 8.3.3.

When I access the photo library on the simulator the UIImagePicker is presented with no problem and I can pick photos. As soon as I try to access the photo library on an actual device (iPhone 7+) the app crashes because the UIImagePicker won’t get presented (I don’t even get to the point to pick a photo). The odd thing is on an actual device the imagePicker presents the camera and I can take photos with no problem.

  • CLLocationManager holds cache value
  • Rectangle and Circle collision detection
  • Xcode 4.5 - CopyPNGFile persists. Need new ideas
  • Generic UITableView keyboard resizing algorithm
  • What is the difference between .dylib and .a lib in ios?
  • Passing parameters to a method called by NSTimer in Swift
  • Even though I didn’t add it inside this question, inside my actual code I have the api permissions running. Inside my actual code I used them and commented them out and the problem still occurs:

    import AVFoundation
    
    //there is way more code then this I just put these here to show that I'm using them
    PHPhotoLibrary.authorizationStatus()
    PHPhotoLibrary.requestAuthorization()
    AVCaptureDevice.authorizationStatus(forMediaType: ...)
    AVCaptureDevice.requestAccess(forMediaType: ...)
    

    UPDATE: I still haven’t resolved the issue but I have found out some more information. I kept playing around with the app and I tried the app again after a crash and it let me access the library. What I came to realize is the app will let me access the library on the phone as long as Xcode isn’t running. As soon as I plug the phone back into Xcode and try to access the library again I get a crash. I don’t know what to make of that.

    As long as Xcode ISN’T hooked up to the device I can successfully obtain photos from the libary. With the simulator I have no problems obtaining photos. With the device NOT hooked up to Xcode I can obtain photos. However once the device and Xcode are connected I get a crash. I’ve tried initializing the UIImagePicker 3 different ways (as stated below) to see if either of them would change the outcome but it’s always the same. My app as over 100 classes and 50 vcs, maybe the problem is happening somewhere else. However if it was happening somewhere else then it should crash when Xcode ISN’T hooked up to the device either.

    Inside the classes that use the UIImagepicker I commented out all the unnecessary code and focused only on the library and camera buttons. The crash always happens once the device and Xcode are intertwined. The good thing is once their not connected I can access the library so the users won’t have a problem because they’ll never have Xcode running with my app.

    It should be noted that when the device and Xcode are hooked up I can use the camera and successfully take pics. The problem seems to be regulated to the library.

    I’ve seen this question asked several times but the answer is always

    “the permissions inside your info.plist have to be set”

    In my situation the permissions are set inside the info.plist:

    info.plist

    source files

    Here is a pic of the Switch that is set to “on” inside the simulator’s Settings page. I couldn’t take a photo of the actual device’s Setting’s page but on there both the Camera and Photos Switches are set to “on”

    permissions

    My code:

    MyController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{ 
    
    fileprivate var imagePicker = UIImagePickerController()
    
    override func viewDidLoad() {
            super.viewDidLoad()
    
            imagePicker.delegate = self
    }
    
    @IBAction fileprivate func libraryButton(_ sender: UIButton){
    
            self.imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
            self.imagePicker.allowsEditing = false
            presentViewController(self.imagePicker, animated: true, completion: nil)
     }
    
    @IBAction fileprivate func cameraButton(_ sender: UIButton){
    
            self.imagePicker.sourceType = UIImagePickerControllerSourceType.camera
            self.imagePicker.allowsEditing = false
            present(self.imagePicker, animated: true, completion: nil)
     }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    
            if let myImage = info[UIImagePickerControllerOriginalImage] as? UIImage{
                imageView.image = myImage
            }
            else if let myImage = info[UIImagePickerControllerEditedImage] as? UIImage{
                imageView.image = myImage
            }
            else{"UIImagePicker Problem")
            }
    
            imagePicker.dismiss(animated: true, completion: nil)
        }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        imagePicker.dismiss(animated: true, completion: nil)
    }
    }
    }
    

    I also tried:

    fileprivate var imagePicker:UIImagePickerController?
    
    @IBAction fileprivate func libraryButton(_ sender: UIButton){
    
            self.imagePicker = UIImagePickerController()
            self.imagePicker?.delegate = self
            self.imagePicker?.sourceType = UIImagePickerControllerSourceType.photoLibrary
            self.imagePicker?.allowsEditing = false
            present(self.imagePicker!, animated: true, completion: nil)
     }
    
    @IBAction fileprivate func cameraButton(_ sender: UIButton){
    
            self.imagePicker = UIImagePickerController()
            self.imagePicker?.delegate = self
            self.imagePicker?.sourceType = UIImagePickerControllerSourceType.camera
            self.imagePicker?.allowsEditing = false
            present(self.imagePicker!, animated: true, completion: nil)
     }
    

    I also tried:

    fileprivate let imagePicker:UIImagePickerController?
    
    override func viewDidLoad() {
            super.viewDidLoad()
    
            imagePicker = UIImagePickerController()
            imagePicker!.delegate = self
    }
    
    
    @IBAction fileprivate func libraryButton(_ sender: UIButton){
    
            imagePicker!.sourceType = UIImagePickerControllerSourceType.photoLibrary
            imagePicker!.allowsEditing = false
            present(imagePicker!, animated: true, completion: nil)
     }
    
    @IBAction fileprivate func cameraButton(_ sender: UIButton){
    
            imagePicker!.sourceType = UIImagePickerControllerSourceType.camera
            imagePicker!.allowsEditing = false
            present(imagePicker!, animated: true, completion: nil)
     }
    

    This is the same crash info I keep getting once the device and Xcode are hooked up:

    libc++abi.dylib`__cxa_throw:
    ->  0x18fd96e70 <+0>:   stp    x22, x21, [sp, #-0x30]!
        0x18fd96e74 <+4>:   stp    x20, x19, [sp, #0x10]
        0x18fd96e78 <+8>:   stp    x29, x30, [sp, #0x20]
        0x18fd96e7c <+12>:  add    x29, sp, #0x20            ; =0x20 
        0x18fd96e80 <+16>:  mov    x19, x2
        0x18fd96e84 <+20>:  mov    x20, x1
        0x18fd96e88 <+24>:  mov    x21, x0
        0x18fd96e8c <+28>:  bl     0x18fd96a88               ; __cxa_get_globals
        0x18fd96e90 <+32>:  mov    x22, x0
        0x18fd96e94 <+36>:  bl     0x18fd9756c               ; std::get_unexpected()
        0x18fd96e98 <+40>:  stur   x0, [x21, #-0x60]
        0x18fd96e9c <+44>:  bl     0x18fd975ac               ; std::get_terminate()
        0x18fd96ea0 <+48>:  stur   x0, [x21, #-0x58]
        0x18fd96ea4 <+52>:  stp    x20, x19, [x21, #-0x70]
        0x18fd96ea8 <+56>:  mov    x8, #0x434c000000000000
        0x18fd96eac <+60>:  movk   x8, #0x4e47, lsl #32
        0x18fd96eb0 <+64>:  movk   x8, #0x432b, lsl #16
        0x18fd96eb4 <+68>:  movk   x8, #0x2b00
        0x18fd96eb8 <+72>:  mov    x19, x21
        0x18fd96ebc <+76>:  str    x8, [x19, #-0x20]!
        0x18fd96ec0 <+80>:  orr    w8, wzr, #0x1
        0x18fd96ec4 <+84>:  stur   x8, [x19, #-0x58]
        0x18fd96ec8 <+88>:  ldr    w8, [x22, #0x8]
        0x18fd96ecc <+92>:  add    w8, w8, #0x1              ; =0x1 
        0x18fd96ed0 <+96>:  str    w8, [x22, #0x8]
        0x18fd96ed4 <+100>: adrp   x8, 0
        0x18fd96ed8 <+104>: add    x8, x8, #0xef8            ; =0xef8 
        0x18fd96edc <+108>: str    x8, [x19, #0x8]
        0x18fd96ee0 <+112>: mov    x0, x19
        0x18fd96ee4 <+116>: bl     0x190433be4               ; _Unwind_RaiseException
        0x18fd96ee8 <+120>: mov    x0, x19
        0x18fd96eec <+124>: bl     0x18fd96f20               ; __cxa_begin_catch
        0x18fd96ef0 <+128>: ldur   x0, [x21, #-0x58]
        0x18fd96ef4 <+132>: bl     0x18fd975c4               ; std::__terminate(void (*)())
    

    I don’t have an Unwind Segue anywhere in my project so I’m unsure of why it says that. But regardless if it works on the simulator it should work on the phone or if it doesn’t work on the phone then it shouldn’t work on the simulator either. Below here is a snippet of the crash report and stack trace.

    Bug Report:

    enter image description here

    enter image description here

    enter image description here

    I deleted the app from the device, shut down Xcode, relaunched it, accepted ok to give it access to the library, and same problem.

    Any idea of what the problem is?

    5 Solutions Collect From Internet About “Swift iOS -UIImagePicker's Photo Library Is Presented On Simulator But Crashes (won't present) On Actual Device While Running Xcode”

    Ash Furrow helped me out with this as it was a very non obvious problem and possibly an api bug. I posted pics for people unfamiliar with the process to resolve it.

    It turns out inside the Breakpoint Navigator I had All Exceptions activated. For some reason when my app was hooked up to Xcode and the UIImagePicker was presenting the photo library, the All Exceptions breakpoint was triggered and there was a slight delay that caused the app to crash. The delay was milliseconds but it was long enough that the app thought that there was a problem. Ash said he never saw anything like that before and said there was possibly a corrupted jpg photo in my photo library but then again it was a wild guess. The simple solution was to deactivate or delete the All Exceptions breakpoint and the problem was resolved. He did say it was possibly an api problem because it was still causing a very odd crash.

    It should be noted that he said that All Exceptions break point is good to keep activated because it will find exceptions earlier then later. I forgot his explanation in detail but basically it’s best to keep it on and if you run into this problem just deactivate it.

    Steps to resolve the UIImagePicker library presentation crash by deactivating the All Exceptions breakpoint:

    1. On the left side of the screen in the navigation pane, the 7th icon from the left that looks like an arrow is the Breakpoint Navigator

    Breakpoint Navigator

    1. The All Exceptions breakpoint is activated/highlighted to blue
      All Exception Activated

    2. To deactivate the ALL Exceptions either click the highlighted blue arrow or right click on the word All Exceptions itself and from the list either choose Disable or Delete

    Options to deselect the All Exception breakpoint

    1. Assuming you either choose Disable or you click the blue arrow, it will be deactivated

    All Exception Deactivated

    1. Obviously if you choose delete it will be erased form the Breakpoint navigator but if you want to add it again (or if you never had it to begin with) then you still have to be inside the Breakpoint Navigator (step 1) and in the lower left corner of the pane you press the plus button and choose Exception Breakpoint to add it.

    Plust button in at the bottom of the pane on the left side

    enter image description here

    Try using below code works perfectly for me

      @IBAction func openLibraryButtonAction(_ sender: Any) {
    
    
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
                let imagePicker = UIImagePickerController()
                imagePicker.delegate = self
                imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary;
                imagePicker.allowsEditing = true
                self.present(imagePicker, animated: true, completion: nil)
            }
    
        }
    
    
     @IBAction func takePhotoButtonAction(_ sender: Any)
    {
    
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)
        {
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = UIImagePickerControllerSourceType.camera;
            imagePicker.allowsEditing = false
            self.present(imagePicker, animated: true, completion: nil)
        }
        else
        {
            noCamera() //Calling alert of No Camera
        }
    }
    
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
        {
            chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
    dismiss(animated:true, completion: nil)
    }
    

    I’m going to justify some suggestions and then paste the resulting snippet.

    • Make sure you inherit from UIViewController in order to use methods like viewDidLoad()
    • imagePicker is set at init, so remove any question marks or if let chaining.
    • For consistency, just remove any ‘self.’ that are not necessary
    • Move any redundant setup to viewDidLoad()

      class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
      
      fileprivate let imagePicker = UIImagePickerController()
      
      override func viewDidLoad() {
      super.viewDidLoad()
      
        imagePicker.delegate = self
        imagePicker.allowsEditing = false
      }
      
      @IBAction fileprivate func libraryButton(_ sender: UIButton) {
      
        imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
        present(imagePicker, animated: true, completion: nil)
      }
      
      func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
      
        if let myImage = info[UIImagePickerControllerOriginalImage] as? UIImage{
          //original image
        }
        else if let myImage = info[UIImagePickerControllerEditedImage] as? UIImage{
          //edited image
        }
        else{
          print("image picker problem")
        }
      
        imagePicker.dismiss(animated: true, completion: nil)
      }
      
      func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
      
        imagePicker.dismiss(animated: true, completion: nil)
      }
      
        }
      

    With these changes you should be good.

    You have to explicitly request an access to image library which uses the UIImagePicker.

    For instance PHPhotoLibrary.requestAuthorization

    The problem in your code is UIImagePickerControllerSourceType.PhotoLibrary, the photo library is change to .photoLibrary p should be in small letter