Privacy keys added but still crash on dismiss UIImagePickerController - swift

Going Crazy。
Using UIImagePickerController to take picture,
After presenting the pickerController, cosole prints
[MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles and [MC] Reading from public effective user settings.
App crashes after dismiss pickerController for 1-2 seconds.
and the console says -[AVCaptureSession release]: message sent to deallocated instance 0x1c4201080
Privacy keys already added:
and the related code sample:
func seletedImage() {
let alertAction = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet)
alertAction.addAction(UIAlertAction.init(title: "拍照", style: .default, handler: { [weak self] (alertCamera) in
self?.showImagePicker(sourceType: .camera)
}))
alertAction.addAction(UIAlertAction.init(title: "从相册中选择", style:.default, handler: { [weak self] (alertPhpto) in
self?.showImagePicker(sourceType: .photoLibrary)
}))
alertAction.addAction(UIAlertAction.init(title: "取消", style: .cancel, handler: nil))
self.present(alertAction, animated: true, completion: nil)
}
func showImagePicker(sourceType: UIImagePickerControllerSourceType) {
if UIImagePickerController.isSourceTypeAvailable(sourceType) == false {
if sourceType == .camera { print("未授予使用相机权限") }
if sourceType == .photoLibrary { print("未授予访问相册权限") }
return
}
let picker: UIImagePickerController = UIImagePickerController()
picker.delegate = self as UIImagePickerControllerDelegate & UINavigationControllerDelegate
picker.sourceType = sourceType
picker.allowsEditing = false
weak var weakself = self
weakself?.present(picker, animated: true, completion: nil)
}
am I missing some other important configurations?
maybe something related to GPUImage?
any help is really really appreciate.
PS. it crashes even I don't take a picture and just cancel directly. the photoLibrary type works fine.

Please handle a case that camera is not available . Please use below code
func SelectFromCamera() {
//Camera
let cameraMediaType = AVMediaTypeVideo
AVCaptureDevice.requestAccess(forMediaType: cameraMediaType) { granted in
if granted {
print("Granted access to \(cameraMediaType)")
if UIImagePickerController.isSourceTypeAvailable(
UIImagePickerControllerSourceType.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType =
UIImagePickerControllerSourceType.camera
imagePicker.mediaTypes = ["public.image"]
// imagePicker.allowsEditing = false
self.present(imagePicker, animated: true,
completion: nil)
}
} else {
//open app setting if not authorize to access camera
print("Denied access to \(cameraMediaType)")
}
}
}

Related

Alert not showing in the ImagePicker

I want to offer the option to use either the photo library or the camera, but my alert to select either photos or use a camera doesn't show up when I add the present actionSheet. The compiled application goes straight to photo album without giving me the option to select camera or photo library.
This is the log from my Xcode 11:
2020-06-15 23:05:22.931477-0400 MeMe[6298:3505455] Attempt to present
on which is waiting for a delayed presention of
to complete 2020-06-15
23:05:22.931653-0400 MeMe[6298:3505455] Attempt to present
on
which is waiting for a delayed presention of to complete error in connection_block_invoke_2:
Connection interrupted
This is my code:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
// OUTLETS *******************************************
// Image
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
// ACTIONS *******************************************
// Button
#IBAction func pickImage(_ sender: Any) {
let imagePickerController = UIImagePickerController()
// set imagePickerController as delegate
imagePickerController.delegate = self
// provide actionSheet to display the camera and photo options
let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", preferredStyle: .actionSheet)
// add camera action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler:{(action:UIAlertAction) in
// check if the camera is available
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
}
else {
print("Camera not available")
}
}))
self.present(imagePickerController, animated: true, completion: nil)
// add photos action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Photos", style: .default, handler:{(action:UIAlertAction) in imagePickerController.sourceType = .photoLibrary}))
self.present(imagePickerController, animated: true, completion: nil)
// cancel
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
// assign image to imageView
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
imageView.image = image
picker.dismiss(animated: true, completion: nil)
}
// dismiss the image selector
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
You're trying to present the actionSheet after presenting imagePickerController which is not possible. You need to present the imagePickerController in the UIAlertAction's handler block. Here's the code:
#IBAction func pickImage(_ sender: Any) {
let imagePickerController = UIImagePickerController()
// set imagePickerController as delegate
imagePickerController.delegate = self
// provide actionSheet to display the camera and photo options
let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", preferredStyle: .actionSheet)
// add camera action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler:{(action:UIAlertAction) in
// check if the camera is available
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
}
else {
print("Camera not available")
}
self.present(imagePickerController, animated: true, completion: nil)
}))
// add photos action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Photos", style: .default, handler:{(action:UIAlertAction) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}))
// cancel
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
#IBAction func pickImage(_ sender: Any) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", 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: "Photos", style: .default, handler:{(action:UIAlertAction) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}))
// cancel
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}

Can't Save UIImage on UIViewController

I've tried to save UIImage on UIViewcontroller named secondViewController, But didn't work.
Code snippet for saving image is attached.
#IBAction func takePhoto(_ sender: Any) {
cameraSession.stopRunning()
UIImageWriteToSavedPhotosAlbum(self.cameraImageView.image!, nil, nil, nil)
}
On SecondViewController, UIImage has been saved to cameraImageView.image,
But when check camera roll, nothing saved.
Does anyone know why?
Add Permission in your info.plist
"Privacy - Photo Library Additions Usage Description"
After permission granted try to save image.
#IBAction func takePhoto(_ sender: Any) {
cameraSession.stopRunning()
UIImageWriteToSavedPhotosAlbum(self.cameraImageView.image!, nil, nil, nil)
}
hey I added full code to capture image using UIImagePickerController and also added code to import a photo from photo gallery, hope it will helpful for you
import UIImagePickerControllerDelegateand create a variable to assign UIImagePickerController var imagePicker = UIImagePickerController()
and set imagePicker.delegate = self.
Create a action sheet to display options for 'Camera' and 'Photo library'.
On your button click action:
#IBAction func buttonOnClick(_ sender: UIButton)
{
self.btnEdit.setTitleColor(UIColor.white, for: .normal)
self.btnEdit.isUserInteractionEnabled = true
let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
self.openCamera()
}))
alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
self.openGallary()
}))
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
/*If you want work actionsheet on ipad
then you have to use popoverPresentationController to present the actionsheet,
otherwise app will crash on iPad */
switch UIDevice.current.userInterfaceIdiom {
case .pad:
alert.popoverPresentationController?.sourceView = sender
alert.popoverPresentationController?.sourceRect = sender.bounds
alert.popoverPresentationController?.permittedArrowDirections = .up
default:
break
}
self.present(alert, animated: true, completion: nil)
}
func openCamera() {
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.camera))
{
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func openGallary() {
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}

how to autocapture an image from camera by using UIImagePickerController in swift

I am trying to capture a picture automatically from camera without clicking the camera capture-button and i am using the UIImagePickerController for camera usage.what should I have to add for autocapture?
class ViewController:UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate
{
var imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
self.openCamera()
}
func openCamera() {
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerController.SourceType.camera)) {
imagePicker.sourceType = UIImagePickerController.SourceType.camera
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
self.imagePicker.dismiss(animated: true, completion: nil)
guard let selectedImage = info[.originalImage] as? UIImage
else{
print("Image not found!")
return
}
}
Here I am clicking the capture button. But I want to take automatically a picture after autofocusing.
It is possible using UIImagePickerController as I R&D on this functionality.
If you want to autocapture an image from camera then you can use this below mentioned code.
1. First you need to Add AVFoundation framework in your project.
Select project -> Add AVFoundation framework in Frameworks, Libraries, and Embedded Content Section
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIGestureRecognizerDelegate {
let objCaptureSession = AVCaptureSession()
var objPreviewLayer : AVCaptureVideoPreviewLayer?
var objCaptureDevice : AVCaptureDevice?
var objImagePicker = UIImagePickerController()
var objTimer: Timer?
var flagRepeatRecording: Bool = false
var objOutputVolumeObserve: NSKeyValueObservation?
let objAudioSession = AVAudioSession.sharedInstance()
override func viewDidAppear(_ animated: Bool) {
if !flagRepeatRecording {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
objImagePicker = UIImagePickerController()
objImagePicker.delegate = self
objImagePicker.sourceType = .camera
objImagePicker.allowsEditing = false
objImagePicker.showsCameraControls = false
//imagePicker.mediaTypes = [kUTTypeMovie as String] // If you want to start auto recording video by camera
} else {
debugPrint("Simulator has no camera")
}
self.present(self.objImagePicker, animated: true, completion: {
self.objImagePicker.takePicture() // If you want you auto start video capturing then replace this code with take picture() method startVideoCapture()
NotificationCenter.default.addObserver(self, selector: #selector(self.cameraIsReady), name: .AVCaptureSessionDidStartRunning, object: nil)
flagRepeatRecording = true
}
}
#objc func cameraIsReady(notification: NSNotification) {
DispatchQueue.main.async {
self.objImagePicker.takePicture()
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// let tempImage = info[UIImagePickerController.InfoKey.mediaURL] as! NSURL?
// let pathString = tempImage?.relativePath
self.dismiss(animated: true, completion: {})
// UISaveVideoAtPathToSavedPhotosAlbum(pathString!, self, nil, nil)
self.objTimer?.invalidate()
self.objTimer = nil
}
}

ImagePickerController function memory leak problems

I am new to programming in general and was having trouble with memory leak problems with the following code specifically involving the "imagePickerController." The leaks only occur after the UIimagePickerController is dismissed after selecting an image. Thank you for any help fixing this.
let imagePicked = UIImagePickerController()
#IBAction func addPhoto(_ sender: UIBarButtonItem) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.allowsEditing = false
imagePicked.delegate = self
let alertController = UIAlertController(title: "Add New Image", message: "Choose From", preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default) { (action) in
pickerController.sourceType = .camera
self.present(pickerController, animated: true, completion: nil)
}
let photosLibraryAction = UIAlertAction(title: "Photos Library", style: .default) { (action) in
pickerController.sourceType = .photoLibrary
self.present(pickerController, animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)
alertController.addAction(cameraAction)
alertController.addAction(photosLibraryAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
#objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
var newImageView = UIImageView()
newImageView = UIImageView(image: image)
newImageView.contentMode = .scaleAspectFit
newImageView.center = textView.center
textView.addSubview(newImageView)
}
dismiss(animated: true, completion: nil)
}
EDIT ONE:
Thank you I have removed #objc in front of didFinishPickingMediaWithInfo as well as the extra UIImagePickerController object, but I am still having the same problem. I have also tried picker.dismiss(animated: true, completion: nil) but that is still not fixing the problem.
And yes I am pretty sure it is a memory leak error as I've ran the tester and after putting pictures into the app from the photos library or the camera I am getting this:
picture 1
picture 2
Also after adding several pictures the app will crash with "Terminated due to memory problem"

How to implement camera in swift

My app always crashes when I press the camera button. I am trying to get the camera to appear on my screen when I press the camera button.
#IBAction func ACPressed(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .camera
present(picker, animated: true, completion: nil)
}
private func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String :AnyObject] ){
camera.image = info [UIImagePickerControllerOriginalImage] as? UIImage; dismiss(animated: true, completion: nil)
}
This is probably a simulator issue. If you want to add code to handle this case, you can do the following:
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)
}
By wrapping it in "isSourceTypeAvailable", it will avoid the crash. You can add an else statement in there and display an alert message notifying of the issue.
Don't use simulator to test the camera. Use real device.
Another way you will see the exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Source type 1 not available'
class ViewController:UIViewController, UIImagePickerControllerDelegate {
private var imagePicker : UIImagePickerController!
private var photo: UIImage?
#IBAction func ACPressed(_ sender: Any) {
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
imagePicker.dismiss(animated: true, completion: nil)
photo = info[UIImagePickerControllerOriginalImage] as? UIImage
}
}
Don't forget to set "Privacy - Camera Usage Description" in your
Info.plist
I don't know why my answer is downvoted but try this code on the real device and you will see that the code works perfect!