UIImagePickerController camera not working swift - ios

I have an action sheet that has two options: one where you can choose an image from your library and one where you can take a photo from the camera. The photo library functions properly, but I can't seem to get the camera to work.
Here is my code:
let takePhoto = UIAlertAction(title: "Take photo", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
// present camera taker
var cameraPicker = UIImagePickerController()
cameraPicker.delegate = self
cameraPicker.sourceType = .Camera
self.presentViewController(cameraPicker, animated: true, completion: nil)
})
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
var selectedAvatar = UIImagePickerControllerOriginalImage
self.dismissViewControllerAnimated(false, completion: nil)
}
I can't seem to find the problem, can anybody help me out? The program crashes when I try to run it and click on Take Photo.

You are most likely running in the simulator. The simulator dont have a camera so to not make the app crash when pressing the button you have to check if cemera is available.
if UIImagePickerController.isSourceTypeAvailable(.Camera) {
...
}
else {
print("Sorry cant take picture")
}

Follow the below code
func takePhoto()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
{
picker!.sourceType = UIImagePickerControllerSourceType.Camera
self .presentViewController(picker!, animated: true, completion: nil)
}
else
{
let alertWarning = UIAlertView(title:"Warning", message: "You don't have camera", delegate:nil, cancelButtonTitle:"OK", otherButtonTitles:"")
alertWarning.show()
}
}
func openGallary()
{
picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(picker!, animated: true, completion: nil)
}
//PickerView Delegate Methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
}
func imagePickerControllerDidCancel(picker: UIImagePickerController)
{
println("picker cancel.")
}

There is another reason why the camera can crash when used in a real device as Kirit Modi said in the following tread:
iOS 10 - App crashes To access photo library or device camera via UIImagePickerController
In iOS 10. You have to set privacy Setting for Camera & Photo Library. Camera & Photo Privacy Setting at info.Plist
This solved my crashing issue!

Related

Inserting a Video from the Photo Library in Xcode

I have set up the insertion of the image from the photo library and now I am trying to let the user also select a video from the photo library or camera roll in iOS. I have written the following code:-
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBAction func didTapOnImageView(sender: UITapGestureRecognizer) {
//call Alert function
self.showAlert()
}
//Show alert to selected the media source type.
private func showAlert() {
var alertStyle = UIAlertController.Style.actionSheet
if (UIDevice.current.userInterfaceIdiom == .pad) {
alertStyle = UIAlertController.Style.alert
}
let alert = UIAlertController(title: "Image Selection", message: "From where you want to pick this image?", preferredStyle: alertStyle)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
self.getImage(fromSourceType: .camera)
}))
alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
self.getImage(fromSourceType: .photoLibrary)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
//get image from source type
private func getImage(fromSourceType sourceType: UIImagePickerController.SourceType) {
//Check is source type available
if UIImagePickerController.isSourceTypeAvailable(sourceType) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = sourceType
imagePickerController.mediaTypes = ["public.image", "public.movie"]
self.present(imagePickerController, animated: true, completion: nil)
}
}
//MARK:- UIImagePickerViewDelegate.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
self.dismiss(animated: true) { [weak self] in
guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
//Setting image to your image view
self?.imageView.image = image
self?.imageView.contentMode = .scaleToFill
self?.image20 = self?.imageView.image
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
It works perfectly fine for choosing the image and displaying it, but, now I am able to select the video but, not display it. Could anyone please help on what shall I include in the imagePickerController delegate to obtain the video URL and display it? Thanks for the help! Appreciate it!
You can definitely catch the vide data from your imagePicker, like so:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
picker.dismiss(animated: true) {
if let image = info[.originalImage] as? UIImage,
let data = image.jpegData(compressionQuality: 0.8) {
}
}
if let videoURL = info[.mediaURL] as? URL {
do {
let videoData = try Data(contentsOf: videoURL, options: .mappedIfSafe)
} catch {
print("Error: \(error.localizedDescription)")
}
}
}
Now, after fetching the Data of your selected video file, your next step is to do the research of playing the video data in a view. You can start from this: Implementing video view in the Storyboard
But take heed of the age of that link, it's from 2015, but it should still help you out.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
videoURL = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerReferenceURL")] as? URL
}
after getting videoURL you can pass it to AVPlayer to play it.
let player = AVPlayer(url: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
present(playerViewController, animated: true) {
playerViewController.player!.play()
}

UIImagePickerController working without NS Photo Library and Camera descriptions

I am working with UIImagePickerController because I am creating an application that allows for the posting of images through both the photo library and camera. I created a basic demo that consists of a UIImageView, UIButton with some code to set up the UIImagePickerController. In addition, I have also set up (NSPhotoLibraryUsageDescription and NSCameraUsageDescription) in the plist section of Xcode. The image picking function works beautifully yet when I run the simulator I am not being queried on whether or not I should let the app allow access to either my camera or photo library. I then tried taking the plist statements off and running again. Without these, the app should crash however it does not. My question is what am I doing wrong here for the picker to work without the plist and why does the app not ask for permissions with the NS usage statements?
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBAction func importImage(_ sender: UIButton) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let actionSheet = UIAlertController(title: "Add Your Profile Picture", message: "Choose An Option", preferredStyle: . actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action:UIAlertAction) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
}
else {
print("Camera not Available")
}
}))
actionSheet.addAction(UIAlertAction(title: "Camera Roll", style: .default, handler:{ (action:UIAlertAction) in imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil
))
self.present(actionSheet, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
imageView.image = image
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Storyboard View
plist image
why does the app not ask for permissions with the NS usage statements
This is due to a change in iOS 11. You no longer need user authorization merely to receive a UIImage through the UIImagePickerController.
But if you want deeper information, i.e. access to the image as a PHAsset and its metadata, you do need user authorization.
And of course if you want this app to run on iOS 10 and before, you'll still need user authorization.

UIImagePickerController throwing SIGABRT

I am experimenting with UIImagePickerController to allow photos to be selected from either the library or by taking a photo with the camera.
I followed the steps on a website (https://makeapppie.com/2016/06/28/how-to-use-uiimagepickercontroller-for-a-camera-and-photo-library-in-swift-3-0/) and got this working for the photo library but whenever I try to invoke the camera from my app it gives the error "Thread 1: signal SIGABRT".
This is the code that I am using to invoke the camera:
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,animated: true,completion: nil)
It was my understanding that the SIGABRT error would be expected inside the simulator. However when I tried it on my iPhone 7 I expected it to work and it gave the same error.
I have added the "Privacy - Camera Usage Description" to the Info.plist file.
Any ideas what I have done wrong?
Here's my full code for using/selecting
// MARK: Camera App
func openCameraApp() {
if UIImagePickerController.availableCaptureModes(for: .rear) != nil {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,
animated: true,
completion: nil)
} else {
noCamera()
}
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style:.default,
handler: nil)
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
// MARK: Photos Albums
func showImagePicker() {
picker.allowsEditing = false
picker.sourceType = .photoLibrary
//picker.modalPresentationStyle = .Popover
present(picker,
animated: true,
completion: nil)
picker.popoverPresentationController?.sourceView = self.view
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
image = chosenImage
self.performSegue(withIdentifier: "ShowEditView", sender: self)
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: false, completion: nil)
}
// MARK: Seque to EditViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowEditView" {
if let vc = segue.destination as? EditViewController {
vc.image = image
//vc.image = images[0]
}
}
}
Ignore the two commented out lines - those are mine for testing things. This code works on all devices, iOS 9+, all orientations (but remember that iPhone is always displayed portrait), and I've never had any problems in either the simulator (it has no camera) nor a physical device.
Of interest is one thing that could cause an issue (not sure if it's throwing SIGABRT) - I'm checking for a rear camera and throwing up an alert if it doesn't exist. (No check for front camera though. I'm not even sure if anything but an iPod touch doesn't have a front facing camera.)
Also, don't forget to add two things to your info.plist for iOS 10:
<key>NSCameraUsageDescription</key>
<string>Used to capture new image for photo effect</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to select an image for photo effect</string>
You may put whatever you want in the description tags. Without these, the app will shut down in iOS 10 and Apple will reject your submission. Here's a link to more details.

EXC_BREAKPOINT on dismissing an UIImagePickerViewController while in Landscape mode

I am working on a chat app with picture messaging (supports Portrait and Landscape orientations), recently updated to Swift 2.3.
I am running into this problem where dismissing the UIImagePickerController results in the app crashing with a EXC_BREAKPOINT (in both cases "Use Photo" and "Cancel"), and cannot for the life of me figure out what is causing it. Removing the self.dismissViewControllerAnimated(true, completion: nil) line removes the crash (though leaves the picker on the screen), so I believe that the root of the problems lies there.
Here is how I set up and call the UIImagePicker:
let takePhotoAction = UIAlertAction(title: "Take a Photo", style: .Default, handler: { (alert: UIAlertAction!) -> Void in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {
let imagePicker = UIImagePickerController();
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera;
self.presentViewController(imagePicker, animated: true, completion: nil)
}
})
And here are the methods that handle the event that an image was picked.
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
if image != nil {
print("Got image");
uploadToS3(image!);
}
self.dismissViewControllerAnimated(true, completion: nil)
}
Any help would be appreciated!

Getting video using UIImagePickerController

I'm trying to get a selected video from an iOS app using UIImagePickerController, and so far when the button is clicked it opens the PhotoLibrary perfectly fine and I select a video and it says compressing video, so it's acting like its selecting it but after that nothing really happens. And I can't really seem to figure out why.
var picker = UIImagePickerController()
var imag = UIImagePickerController()
...
#IBAction func selectMediaAction(sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){
picker.delegate = self
picker.allowsEditing = false
picker.mediaTypes = [kUTTypeMovie as String]
self.presentViewController(picker, animated: true, completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {
let media = editingInfo[UIImagePickerControllerOriginalImage]
let imageURL = media?.filePathURL as NSURL?
mediaPath = imageURL
mediaName.text = imageURL!.lastPathComponent
self.dismissViewControllerAnimated(true, completion: nil)
toggleSubmit()
}
#IBAction func createMediaAction(sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
imag.delegate = self
imag.allowsEditing = false
imag.sourceType = UIImagePickerControllerSourceType.Camera
imag.mediaTypes = [kUTTypeMovie as String]
self.presentViewController(imag, animated: true, completion: nil)
} else{
let alert = UIAlertController(title: nil, message: "There is no camera available on this device", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
Am I missing something? It looks to me like it should be working
The code you have will only check for the image types. If you want to get the selected video information, you need to look for the key UIImagePickerControllerMediaType and you need to use the delegate method didFinishPickingMediaWithInfo not the didFinishPickingImage
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];

Resources