UIImagePickerController crashes app | Swift3, Xcode8
Solution 1
Add this key to your info.plist
,
Key : Privacy - Photo Library Usage Description [ NSPhotoLibraryUsageDescription ]
String Value : We need access to your camera roll and photo library, so that we can do operations on it. [ Customise it in your own way]
That's it, Clean & Run
the project.
Solution 2
In xcode 8 new key is added Privacy For -
Media,Location,Photo Library,Reminders,Motion,Calender,Bluetooth,HomeKit,Camera,Contacts etc.. and value is Description for the privacy you will access for.For ex. "We need access to use photo library to make functionality work" or ANY_YOUR_APP_RELATED_DESCRIPTION.
Solution 3
Noticed a camera key and value needed for camera usage as well.
Keys required for both the camera and photo library that need to be in the info.plist:
<key>NSCameraUsageDescription</key>
<string>Access needed to use your camera.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Access needed to photo gallery.</string>
Related videos on Youtube
ARS
Updated on June 25, 2022Comments
-
ARS almost 2 years
FYI: I´m new to Swift so this might be a really simple problem but I just can´t figure it out.
I have been following the Start Developing iOS Apps (Swift) tutorial using the Xcode 8 beta and Swift 3.
I attached a Tap Gesture Recognizer to a Image View and then added this action in the ViewController.swift :
@IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) { // Hide the keyboard. nameTextField.resignFirstResponder() // UIImagePickerController is a view controller that lets a user pick media from their photo library. let imagePickerController = UIImagePickerController() // Only allow photos to be picked, not taken. imagePickerController.sourceType = .photoLibrary // Make sure ViewController is notified when the user picks an image. imagePickerController.delegate = self present(imagePickerController, animated: true, completion: nil) }
When the selectImageFromPhotLibrary Action is called by a tap on the Image View the app crashes without showing the ImagePicker.
I guess that the problem is with the new present instead of presentViewController which was introduced in Swift 3
ViewController.swiftimport UIKit class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate { // MARK: Properties @IBOutlet weak var mealNameLabel: UILabel! @IBOutlet weak var nameTextField: UITextField! @IBOutlet weak var photoImageView: UIImageView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // Handle the text field´s user input through delegate callbacks nameTextField.delegate = self } // MARK: UITextFieldDelegate func textFieldShouldReturn(_ textField: UITextField) -> Bool { // Hide the keyboard. textField.resignFirstResponder() return true } func textFieldDidEndEditing(_ textField: UITextField) { mealNameLabel.text = textField.text } // MARK: UIImagePickerControllerDelegate func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { // Dismiss the picker if the user canceled. dismiss(animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { // The info dictionary contains multiple representations of the image, and this uses the original. let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage // Set photoImageView to display the selected image. photoImageView.image = selectedImage // Dismiss the picker. dismiss(animated: true, completion: nil) } // MARK: Actions @IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) { // Hide the keyboard. nameTextField.resignFirstResponder() // UIImagePickerController is a view controller that lets a user pick media from their photo library. let imagePickerController = UIImagePickerController() // Only allow photos to be picked, not taken. imagePickerController.sourceType = .photoLibrary // Make sure ViewController is notified when the user picks an image. imagePickerController.delegate = self present(imagePickerController, animated: true, completion: nil) } @IBAction func setDefaultLabelText(_ sender: UIButton) { mealNameLabel.text = "Default Text" } }
Console Output2016-06-20 17:08:20.568093 FoodTracker[33322:696094] bundleid: com.armin.FoodTracker, enable_level: 0, persist_level: 0, propagate_with_activity: 0 2016-06-20 17:08:20.569458 FoodTracker[33322:696094] subsystem: com.apple.UIKit, category: HIDEvents, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0 2016-06-20 17:08:20.604909 FoodTracker[33322:696090] Created DB, header sequence number = 288 2016-06-20 17:08:20.668341 FoodTracker[33322:696090] Created DB, header sequence number = 288 2016-06-20 17:08:20.743143 FoodTracker[33322:696090] subsystem: com.apple.BaseBoard, category: MachPort, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0 2016-06-20 17:08:20.769881 FoodTracker[33322:696091] subsystem: com.apple.FrontBoard, category: Common, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0 2016-06-20 17:08:22.007665 FoodTracker[33322:695971] subsystem: com.apple.UIKit, category: Touch, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0 2016-06-20 17:08:22.009799 FoodTracker[33322:695971] subsystem: com.apple.UIKit, category: Gesture, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0 2016-06-20 17:08:22.012973 FoodTracker[33322:695971] subsystem: com.apple.UIKit, category: GestureEnvironment, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0 2016-06-20 17:08:22.013820 FoodTracker[33322:695971] subsystem: com.apple.UIKit, category: GestureExclusion, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0 2016-06-20 17:08:23.061815 FoodTracker[33322:695971] subsystem: com.apple.photos, category: Generic, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0
-
Alexander almost 8 yearsYou'd think that when posting about an error, it'd be useful to post the error.
-
abraaoan almost 8 yearsYou call a wrong method. You should call like this: self.presentViewController(imagePickerController, animated: true, completion: nil)
-
ARS almost 8 years@AMomchilov there is no error message. The app just closes/crashes
-
Alexander almost 8 yearsCheck the console after it crashes
-
ARS almost 8 years@abraaoan I already tried that initially but then i get a error saying: "presentViewController(:animated:completion:) has been renamed to preent(:animated:completion:)"
-
ARS almost 8 years@AMomchilov Added the console output in the question
-
Dave Sieving over 7 years
self.presentViewController(imagePickerController, animated: true, completion: nil)
is an example of the old Swift syntax specified in the instructional material. When Xcode is updated to Version 8.0 (8A218a), it prompts the user to update any old Swift syntax it finds to Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38). The ViewController.swift code shown above uses the new syntax.
-
-
stackflow over 7 yearstnx, helped me to visualize
-
rmaddy over 7 yearsYou don't set the value to
YES
. You set it to a short message that is displayed to the user. -
rmaddy over 7 yearsWhy are the values set to "YES"? They should be short messages that are shown to the user.
-
Admin over 7 years@rmaddy Yeah right, they have changed it in the new Xcode. I have modified my answer.
-
rickster over 7 yearsGood catch. I'd recommend filing a bug to Apple about that tutorial so you can follow it getting fixed.
-
rickster over 7 yearsAlso, you should need only "Photo Library Usage Description" for this project, not "Media Library Usage Description". The latter is for using frameworks like MediaPlayer to access Music and other iTunes-synced content, which this tutorial project doesn't do.
-
Admin over 7 years@rickster Yeah you are correct. I forgot about that, I just put it there to give an overall concept about these new keys. Thanks for pointing it out.
-
Echelon over 7 yearsSame for NSCameraUsageDescription - if you launch the camera without it, you get an extremely unhelpful crash.
-
rickrizzo over 7 yearsAnother issue I found after I implemented this fix was that I was creating an image format with an unknown type. Changing AnyObject to Any fixed this: func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
-
Joseph Astrahan over 7 yearsFor video add the Privacy - Microphone Usage as well or it will still crash.
-
javimuu about 7 yearsThanks, it help me very much!
-
Maninder Singh about 7 yearsFor me the dismiss is not working. When i click on the button 'use photo' the camera pop up again and again. Is there a way to make it work?
-
Maninder Singh about 7 yearsFor me the dismiss is not working. When i click on the button 'use photo' the camera pop up again and again. Is there a way to make it work?