Swift iOS -UIImagePicker的照片库在模拟器上呈现,但崩溃(不会出现)在运行Xcode的实际设备上

我在Swift 3,iOS 10.3和Xcode 8.3.3上。

当我在模拟器上访问照片库时,UIImagePicker没有问题,我可以select照片。 只要我尝试访问实际设备(iPhone 7 +)上的照片库,应用程序崩溃,因为UIImagePicker不会呈现 (我甚至没有到点select一张照片)。 奇怪的是在一个实际的设备imagePicker介绍相机,我可以拍照没有问题。

即使我没有把它添加到这个问题里面,在我的实际代码里,我已经运行了api权限。 在我的实际代码中,我使用了它们,并将它们评论出来,问题仍然存在:

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: ...) 

更新:我仍然没有解决这个问题,但我发现了一些更多的信息。 我一直玩这个应用程序,并在崩溃后再次尝试应用程序,并让我进入图书馆。 我开始意识到,只要Xcode没有运行,应用程序就会让我访问电话上的库。 只要我把手机插回Xcode,并尝试再次访问库,我得到一个崩溃。 我不知道该怎么做。

只要Xcode不是连接到设备,我可以成功地从库中获取照片 。 与模拟器,我没有问题,获得照片。 随着设备没有连接到Xcode我可以获得照片。 但是,一旦设备和Xcode连接,我得到一个崩溃。 我已经尝试初始化UIImagePicker 3种不同的方式(如下所述),看看他们中的任何一个是否会改变结果,但总是一样的。 我的应用程序超过100个类和50个vcs,也许问题发生在别的地方。 但是,如果它发生在别的地方,那么当Xcode没有连接到设备时,它应该会崩溃。

在使用UIImagePicker的类中,我注释掉了所有不必要的代码,并仅将注意力集中在库和相机button上。 一旦设备和Xcode交织在一起,崩溃总是会发生。 好东西是一旦他们没有连接,我可以访问库,所以用户不会有问题,因为他们永远不会有Xcode与我的应用程序运行。

应该注意的是,当设备和Xcode挂钩时,我可以使用相机,并成功地拍照。 这个问题似乎是受到图书馆的pipe制的。

我已经多次看到这个问题,但答案总是如此

“你的info.plist中的权限必须设置”

在我的情况下,权限是在info.plist中设置的:

info.plist中

源文件

这里是在模拟器的设置页面中设置为“开”的开关的图片。 我无法拍摄实际设备的“设置”页面的照片,但在相机和照片开关均设置为“开”

权限

我的代码:

 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) } } } 

我也试过:

 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) } 

我也试过:

 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) } 

这是一旦设备和Xcode连接起来的同一个崩溃信息:

 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 (*)()) 

我的项目中没有任何一个Unwind Segue,所以我不确定为什么这么说。 但是,不pipe它是否在模拟器上工作,它应该在手机上工作,或者如果它不能在手机上工作,那么它也不应该在模拟器上工作。 下面是这个崩溃报告和堆栈跟踪的一个片段。

错误报告:

在这里输入图像说明

在这里输入图像说明

在这里输入图像说明

我从设备上删除了应用程序,closures了Xcode,重新启动了它,接受了可以给它访问的库,以及相同的问题。

任何想法是什么问题?

Ash Furrow帮我解决了这个问题,因为这是一个非常明显的问题,可能还有一个API错误。 我张贴照片为不熟悉的过程解决它。

事实certificate,在Breakpoint Navigator我激活了All Exceptions 。 出于某种原因,当我的应用程序连接到Xcode和UIImagePicker呈现照片库,所有exception断点被触发,并有一个轻微的延迟,导致应用程序崩溃。 延迟是毫秒,但它足够长,应用程序认为有问题。 阿什说,他从来没有见过这样的事情,并说我的照片库中可能有一张腐败的JPG照片,但这又是一个疯狂的猜测。 简单的解决scheme是停用或删除所有exception断点,并解决了问题。 他确实说过这可能是一个api问题,因为它仍然造成了一个非常奇怪的崩溃。

应该指出的是,他说所有exception断点都是很好的保持激活状态,因为它会在之前和之后发现exception。 我忘记了他的详细解释,但基本上最好保持它,如果遇到这个问题就停用它。

通过停用所有exception断点来解决UIImagePicker库演示文稿崩溃的步骤:

  1. 在导航窗格的左侧屏幕中,左侧的第7个图标看起来像箭头,是Breakpoint Navigator

断点导航器

  1. 所有例外断点被激活/高亮显示为蓝色 所有例外激活

  2. 要取消所有例外情况,请点击高亮显示的蓝色箭头,或者右键点击All Exceptions本身,然后从列表中select禁用或删除

取消所有异常断点的选项

  1. 假设你select禁用或者点击蓝色箭头,它将被停用

所有异常停用

  1. 很明显,如果你select删除,它将从断点导航器中被删除,但是如果你想再次添加它(或者你从来没有开始过),那么你仍然必须在断点导航器(步骤1)中,您按下加号button,然后select“exception断点”来添加它。

点击左侧窗格底部的按钮

在这里输入图像说明

尝试使用下面的代码完全适合我

  @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) } 

我要certificate一些build议,然后粘贴结果摘录。

  • 确保你从UIViewControllerinheritance,以便使用像viewDidLoad()
  • imagePicker设置在init,所以删除任何问号或if let链接。
  • 为了一致性,只要删除任何“自我”。 这是没有必要的
  • 将任何多余的设置移动到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) } } 

有了这些改变,你应该很好。

您必须明确请求访问使用UIImagePicker图像库。

例如PHPhotoLibrary.requestAuthorization

在你的代码中的问题是UIImagePickerControllerSourceType.PhotoLibrary ,照片库改为.photoLibrary p应该是小写字母