6

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.

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?

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • has you set `mediaTypes` property of `UIImagePickerController` class? – Sanjay Shah Aug 21 '17 at 05:05
  • @SanjayShah hey thanks for the help! I don't know what you mean by the "mediaTypes" property – Lance Samaria Aug 21 '17 at 05:06
  • please refer this simple class hope which helps you out. https://github.com/ujeshpatel/MediaPicker – Sanjay Shah Aug 21 '17 at 05:08
  • `imagePickerController.mediaTypes = [kUTTypeImage as String]` you can set `mediaTypes` property like this for image only. Same as you can set video also `[kUTTypeMovie as String]`. – Sanjay Shah Aug 21 '17 at 05:09
  • @SanjayShah how does this solve the problem though? The problem is the imagePicker won't get presented on the phone but does get presented on the simulator – Lance Samaria Aug 21 '17 at 05:12
  • `imagePicker.dismiss(animated: true, completion: nil)` change this line to `self.dismiss(animated: true, completion: nil)` may be your problem get solved. – Sanjay Shah Aug 21 '17 at 05:15
  • @SanjayShah that can't be the problem because that dismisses the picker. It never gets presented to get dismissed. The nil is because I don't want anything done in its completionHandler. Besides if that was it it shouldn't work on the simulator. – Lance Samaria Aug 21 '17 at 05:18
  • add some delay before presenting it and it will work... – Ravi Panchal Aug 21 '17 at 05:18
  • @ravi.p thanks. I will try it – Lance Samaria Aug 21 '17 at 05:19
  • @ravi.p I added a 2 second delay. That doesn't work. It also doesn't answer the question on why it works with the simulator but not on the phone. Thanks anyway though – Lance Samaria Aug 21 '17 at 05:36
  • @LanceSamaria i know that it is not the answer of your question, but in my case it will work like charm and you can also see this answer may be it will hlep u out .. https://stackoverflow.com/questions/39995544/ios-swift-3-uiimagepickercontroller-crash – Ravi Panchal Aug 21 '17 at 05:49
  • @ravi.p I'll try it. Thanks! – Lance Samaria Aug 21 '17 at 06:34
  • show your complete debug report not only the crash log – Abdul Waheed Aug 21 '17 at 11:01
  • "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" Fair enough. If you have a reproducible case, I would recommend that you file a bug with Apple. – matt Aug 22 '17 at 16:12
  • @matt thanks for the advice. I'm not really sure what the issue is. Im going to a meetup this weekend. Ash Furrow and Orta organize it. I'm not sure if you heard of them but they're really high level devs. Maybe they can help identify this problem. – Lance Samaria Aug 22 '17 at 16:14
  • @matt the library crash problem is resolved, it was a very odd issue, check it out when you can – Lance Samaria Aug 27 '17 at 17:39
  • @ravi.p the library presentation problem is resolved, check it out when you can and thanks for the help – Lance Samaria Aug 27 '17 at 18:51

6 Answers6

3

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

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • 2
    I have seen people confuse an exception breakpoint with a crash before; for example, https://stackoverflow.com/a/26985823/341994 But I have never seen an exception breakpoint cause a _real_ crash. As you suggested, that's extremely interesting; again, I strongly urge you to file a bug report with Apple, as that is clearly not supposed to happen. – matt Aug 27 '17 at 18:10
  • @matt thanks for the advice. Ash said the same exact thing you said about ppl mistaking a breakpoint for a crash but never saw it cause one before. That's why he assumed it was a corrupted jpg but again it was a wild guess. I have 2 bug reports to file with Apple that make no sense (this being one of them). Check out this one if you get a chance. Ash looked at the storyboard and code and said it's 100% an api bug: https://stackoverflow.com/questions/45440347/ios-xcode-editing-storyboard-objects-results-in-view-controllers-scenes-duplica .I'm going to file them with Apple once I finish my app. – Lance Samaria Aug 27 '17 at 18:29
  • geez, I would have never figured this out, thanks for that, the app would crash only on some images using UIImagePickerController before it ever got to any of my code to debug, I would suggest as a test, turning off ALL break points to see, because for sure one of the break points triggers a crash using UIImagePickerController, and before it ever gets to the didFinishPicking function. (filing a bug report, sure, the first bug report was 2 years ago... that is how well bug reports work) thank you stack overflow for 'real' bug reports/solutions. – hokkuk Sep 03 '19 at 18:39
0

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)
}
iOS Geek
  • 4,825
  • 1
  • 9
  • 30
  • thanks but this is the same code that I have below the answer where I wrote "I tried...". The only thing you have here is a check if the .photoLibrary is available. I tried it anyway but it's the same crash results. – Lance Samaria Aug 21 '17 at 13:15
  • can I see your codeFile if possible ? as I am unable to detect where crash can be ? – iOS Geek Aug 22 '17 at 03:41
  • the file actually has several hundred lines in it. I condensed it to what you see. I commented hundreds of lines out and focused on this and it still happened. Remember with the simulator the library imagePicker gets presented, on the device as long as Xcode isn't running on it the library imagePicker gets presented, once I hook up Xcode to the device, the crash happens (library imagePicker doesn't get presented). I tried if let, print statements etc. The imagePicker does its job, something else is preventing it from presenting. – Lance Samaria Aug 22 '17 at 03:55
  • I used same code as you had posted and I didn't got any crash maybe you need to check your rest of the code which is causing such crash. – iOS Geek Aug 22 '17 at 04:25
  • hey thanks for the help. I'm not really sure what the issue is as I've commented everything out. It's an odd problem because why doesn't it crash when Xcode isn't hooked up. If it crashed while Xcode was on and off then it'd be easier to diagnosis. Thanks though. I guess I have to keep trying. The users won't use Xcode so at least it will still work for them. – Lance Samaria Aug 22 '17 at 04:28
  • yes true your code works perfectly even if my Xcode is hooked with device or not. – iOS Geek Aug 22 '17 at 04:29
  • have you ever heard of such a problem? – Lance Samaria Aug 22 '17 at 04:30
  • No, I never heard or faced such problem. what else keys are you using in info.plist try checking them – iOS Geek Aug 22 '17 at 04:31
  • the permission keys I listed in the question are the exact keys I'm using – Lance Samaria Aug 22 '17 at 11:37
  • the library crash problem is resolved, it was a very odd issue, check it out when you can and thanks for the help – Lance Samaria Aug 27 '17 at 17:40
0

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.

gioneill
  • 21
  • 2
  • hey thanks for he help! I actually don't use self. anywhere in my code except closures. I added it here for ppl new to Swift/Xcode for clarity. I initially had the imagePicker initialized at class level, I changed it because I wasn't sure what the problem was. I commented out every single unnecessary line of code and only kept it so that I can press the buttons for the library and camera. No matter what happens I can get to the library and use photos on the simulator and device w/o Xcode so it does work. Once I hook the device up to Xcode the crash occurs because the picker won't present. – Lance Samaria Aug 22 '17 at 15:42
  • I just tried your suggestion of removing allowsEditing and putting it inside viewDidLoad, the crash still happens if the device is hooked up to Xcode. As soon as it crashed, I shut down Xcode, launchd the app, and everything was fine. It only happens when the 2 are connected. Thanks for your help though :) – Lance Samaria Aug 22 '17 at 16:01
  • the library crash problem is resolved, it was a very odd issue, check it out when you can and thanks for the help – Lance Samaria Aug 27 '17 at 17:38
0

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

For instance PHPhotoLibrary.requestAuthorization

Nik Yekimov
  • 2,657
  • 2
  • 24
  • 34
  • thanks for the help. I actually have that in my code. It's for the permissions. I didin't add it in my question because I commented it out and the error still occurs. However if that was the reason then I wouldn't;t be able to access the library when Xcode isn't hooked up nor on the simulator. With or without the PHPhotoLibrary.requestAuthorization the problem occurs once the device and Xcode are hooked up. Other then that everything is fine. – Lance Samaria Aug 22 '17 at 16:21
  • @LanceSamaria does the device have camera? – Nik Yekimov Aug 22 '17 at 16:22
  • yes, it's an iPhone 7+ and it works fine when Xcode is hooked up AND when it isn't hooked up. I can successfully take pictures in both scenarios. That's why this is so mind boggling. Only the library is inaccessible when Xcode and the device are together. Here's the thing though, I put break points and print statements on the "present" line and they always run perfectly. Something is happening during the presentation. – Lance Samaria Aug 22 '17 at 16:25
  • thanks for bringing that to my attention. Event though I use it in my actual code ppl may think that I'm not using it since I didn't include it in my question. I'm going to add that to my question – Lance Samaria Aug 22 '17 at 16:41
  • the library crash problem is resolved, it was a very odd issue, check it out when you can and thanks for the help – Lance Samaria Aug 27 '17 at 17:40
0
**- I'm also facing the same problem after selecting any image from gallery. after lots of effects I found this solution.**

if #available(iOS 14, *) {
            var config = PHPickerConfiguration()
            config.filter = .images
            config.selectionLimit = 1
            let picker = PHPickerViewController(configuration: config)
            picker.delegate = self
            self.currentController.present(picker, animated: true)
        } else {
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary) {
                self.imagePicker.delegate = self
                self.imagePicker.allowsEditing = false
                self.imagePicker.sourceType = .savedPhotosAlbum
                self.currentController.present(imagePicker, animated: true, completion: nil)
            } else {
                let alert  = UIAlertController(title: "Warning", message: "You don't have permission to access gallery.", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                self.currentController.present(alert, animated: true, completion: nil)
            }
        }


extension USE_YOUR_CLASS_NAME: PHPickerViewControllerDelegate {
    @available(iOS 14, *)
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        guard let result = results.first else { return }

        let jpeg = UTType.jpeg.identifier
        let prov = result.itemProvider
        prov.loadFileRepresentation(forTypeIdentifier: jpeg) { urlMaybe, errorMaybe in
            guard let url = urlMaybe else { return }

            let imageData:NSData = NSData(contentsOf: urlMaybe!)!
            let image = UIImage(data: imageData as Data)
            if image != nil {
                // YOU'LL GET SELECTED IMAGE HERE..
            }
        }
    }
}


extension USE_YOUR_CLASS_NAME: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
    //guard let fileUrl = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
    debugPrint(selectedImgName)
    
    if let chosenImage = info[.originalImage] as? UIImage {
        // YOU'LL GET SELECTED IMAGE HERE..
    }
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    currentController.dismiss(animated: true, completion: nil)
}
}
V.Kumar
  • 139
  • 2
  • 5
-1

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

Wide Angle Technology
  • 1,184
  • 1
  • 8
  • 28
  • That was a clerical error. Did you read the entire answer? The code below where I wrote "I also tried..." I do have it lower case and besides that I wouldn't be able to launch it on the simulator at all because Xcode would throw an error. – Lance Samaria Aug 21 '17 at 13:08