Using camera with Mac Catalyst - ios

In an app ported to Mac Catalyst, the camera interface always turned out to be blank.
I have checked: the capabilities includes "Camera", the privacy setting in info.plist is there (the iPad app shows the camera fine), and I even try to include front camera for UIImagePickerController.
if UIImagePickerController.isSourceTypeAvailable(.camera) {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .camera
imagePicker.delegate = self
imagePicker.cameraDevice = .front // added for Mac
self.present(imagePicker, animated:true, completion:nil)
}
The error I got is: "[Generic] Could not create video device input: Error Domain=AVFoundationErrorDomain Code=-11814"

I have the same mistake, I'm afraid it's a bug ...
Everything works correctly on iOS and iPadOS.
For the moment I think there's no way to make it work...

You need Requesting Authorization for Media Capture on macOS
import AVFoundation
AVCaptureDevice.requestAccess(for: .video) { granted in
let ctrl = UIImagePickerController()
ctrl.sourceType = .camera
self.present(ctrl, animated: true, completion: nil)
}
Add to info.plist
<key>NSCameraUsageDescription</key>
<string> .... </string>

Related

How can I stream iPhone Camera Data over USB as a webcam?

I am familiar with the simple solution of just streaming over the devices screen, and bringing up a preview window and just showing the camera preview.
let picker: UIImagePickerController = CustomUIImagePickerController()
picker.delegate = self;
picker.sourceType = .camera
picker.setNavigationBarHidden(true, animated: false)
picker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String]
picker.cameraCaptureMode = UIImagePickerController.CameraCaptureMode.video
picker.videoQuality = UIImagePickerController.QualityType.typeHigh
picker.showsCameraControls = false
picker.cameraViewTransform.ty += 100;
present(picker, animated: true, completion: nil)
The above solution only streams at a resolution of the device screen. I need a way to use the iPhone back camera as a 4k 30fps webcam. I know I can use AVCam to Write a video to file with 4k # 30fps, but I don't know how to stream it over USB.

Xcode Camera: Failed to read exposureBiasesByMode dictionary

I recently got this error with the UIImagePickerController in Xcode Version 12.0.1
[Camera] Failed to read exposureBiasesByMode dictionary: Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: data is NULL" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: data is NULL}
Has anyone else seen this error? How do you fix it?
If you customize your image picker as imagePicker.allowsEditing = true
you have to fetch image using:
if let pickedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
capturedImage = pickedImage
}
If you instead use imagePicker.allowsEditing = false, use this to pick image:
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
capturedImage = pickedImage
}
If you don't follow this combination, you may get this error.
in my case, I got this bug from trying to use the image data and syncing with Files. Adding this permission in Info.plist made all the difference and made that error go away:
<key>LSSupportsOpeningDocumentsInPlace</key> <true/>
I experienced the same issue. I imported AVKit instead og AVFoundation and tried to present the video in the native recorder view. That gave me an exception telling me to add NSMicrophoneUsageDescription to the info.plist file, and after this, I was able to display the live video in a custom view.
So I believe the issue is with iOS 14 being very picky about permissions, and probably something goes wrong with showing the correct exception when the video is not presented in the native view.
Anyway, this worked for me:
import AVKit
import MobileCoreServices
#IBOutlet weak var videoViewContainer: UIView!
private let imagePickerController = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
initCameraView()
}
func initCameraView() {
// Device setup
imagePickerController.delegate = self
imagePickerController.sourceType = .camera
imagePickerController.mediaTypes = [kUTTypeMovie as String]
imagePickerController.cameraCaptureMode = .video
imagePickerController.cameraDevice = .rear
// UI setup
addChild(imagePickerController)
videoViewContainer.addSubview(imagePickerController.view)
imagePickerController.view.frame = videoViewContainer.bounds
imagePickerController.allowsEditing = false
imagePickerController.showsCameraControls = false
imagePickerController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
And then the added description for the NSMicrophoneUsageDescription in the info.plist file :-)
Hope it will work for you as well!
I managed to solve the problem. In fact, it is not directly related to react-native-image-crop-picker. The problem was that I was using react-native-actionsheet to give the user the option to open the camera or the gallery. When I opened the react-native-actionsheet and pressed one of the options, the camera was superimposing the react-native-actionsheet (modal) which generated a conflict, because apparently in IOS it is not possible for one Modal to overlap the other.
So, to solve the problem, I defined a timeout so that it is possible to close the modal before opening the camera.
I got this error when I tried to copy from a URL I couldn't copy. Which was coming from the mediaURL from the UIImagePickerControllerDelegate.
Basically, what I did was to use UISaveVideoAtPathToSavedPhotosAlbum
Like in this example ⤵️
if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(url.absoluteString) {
UISaveVideoAtPathToSavedPhotosAlbum(url.absoluteString, self, #selector(self.didSaveVideo), nil)
} else {
return /* do something*/
}
#objc private func didSaveVideo(videoPath: String, error: NSError, contextInfo: Any) {}
I found the same error with Xcode 12 & iOS 14 when imagePicker's source type is camera.
But the app is working fine, I could take picture using camera and put it in my collection view cell. Thus, maybe something on Xcode 12 I guess.
#objc func addPerson() {
let picker = UIImagePickerController()
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.sourceType = .camera
} else {
fatalError("Camera is not available, please use real device.")
}
picker.allowsEditing = true
picker.delegate = self
present(picker, animated: true)
}
I faced the same error with Xcode 12 & iOS 14.
But in my case, I used ActionSheet to choose camera or photo library before that. So I changed to open camera just after close that ActionSheet, and it works well.
Hope this will be helpful on your issue.
enum MediaOptions: Int {
case Photos
case Camera
}
func selectImage(mediaType: MediaOptions) {
self.mediaOption = mediaType
let iPicker = UIImagePickerController()
iPicker.delegate = self
iPicker.allowsEditing = false
if mediaType == .Camera {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
iPicker.sourceType = .camera
iPicker.allowsEditing = true
}
} else {
iPicker.sourceType = .photoLibrary
}
self.present(iPicker, animated: true, completion: nil)
self.imagePicker = iPicker
}
func choosePhoto() {
let actionSheet = UIAlertController(title: "Choose", message: "", preferredStyle: .actionSheet)
if UIImagePickerController.isSourceTypeAvailable(.camera) {
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action) -> Void in
actionSheet.dismiss(animated: true) {
self.selectImage(mediaType: .Camera) // Just moved here - inside the dismiss callback
}
}))
}
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
actionSheet.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action) -> Void in
self.selectImage(mediaType: .Photos)
}))
}
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
In my case, I was missing an Info.plist key for NSCameraUsageDescription.
You should enter the purpose of using camera as the description.
It fixed the crash for me.
Plus, if you don't give the purpose, your app is likely to be rejected.
If like me you have this second message :
[access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.
Then you have to add this to your info.plist dictionary:
<key>NSCameraUsageDescription</key>
<string>so you can choose a photo or take a picture for object detection</string>
It solved the problem for me

Open Camera Programmatically Through iOS App - Deep Link?

I want to create an IBAction to open the iOS native camera app in my app, but I can't seem to find the address for the camera app online.
I know for messages it's: UIApplication.shared.open(URL(string: "sms:")!, options: [:], completionHandler: nil)
Does anyone know which is the correct scheme?
I suggest you to follow a clean way doing so:
let cameraVc = UIImagePickerController()
cameraVc.sourceType = UIImagePickerControllerSourceType.camera
self.present(cameraVc, animated: true, completion: nil)
in such case you must add into the Info.plist:
<key>NSCameraUsageDescription</key>
<string>whatever</string>
Here we suggest you to user the following github :
https://github.com/shantaramk/AttachmentHandler
!. 1. Drag drop the AttachmentHandler folder in project folder
func showCameraActionSheet() {
AttachmentHandler.shared.showAttachmentActionSheet(viewController: self)
AttachmentHandler.shared.imagePickedBlock = { (image) in
let chooseImage = image.resizeImage(targetSize: CGSize(width: 500, height: 600))
self.imageList.insert(chooseImage, at: self.imageList.count-1)
self.collectionView.reloadData()
}
}
Swift 5 version, after adding NSCameraUsageDescription in your Info.plist:
let cameraVc = UIImagePickerController()
cameraVc.sourceType = UIImagePickerController.SourceType.camera
self.present(cameraVc, animated: true, completion: nil)

UIImagePickerController crashes when video button is tapped

Following code works good when capturing photo using camera, but app crashes when user taps on video.
let imagePicker = UIImagePickerController()
imagePicker.modalPresentationStyle = .currentContext
imagePicker.delegate = self
if let _ = UIImagePickerController.availableMediaTypes(for: .camera) {
imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .camera)!
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
}
I had a similar problem and it was due to not asking for microphone usage permission in my Info.plist.
Check that you have a proper value for:
NSCameraUsageDescription (Privacy - Camera Usage Description)
NSMicrophoneUsageDescription (Privacy - Microphone Usage Description)
NSPhotoLibraryUsageDescription (Privacy - Photo Library Usage Description)
Then when you change from photo mode to video mode your app will ask for microphone access instead of just crashing.

Swift - Is it possible to select a video from the library on the iOS simulator?

All that shows up when I use the UIImagePickerController is a library of photos. I have an mp4 video saved to the simulator library, but it never shows up in the list when I access the simulator library programmatically with UIImagePickerController. Is there something I'm doing wrong?
You just need to add a video to your simulator.
Drag and drop a video file on top of the simulator window. It will show in the photos app and whenever you want a video for upload.
Based on Swift 2.2
Your code may look like this:
#IBAction func selectImageFromPhotoLibrary(sender: UIBarButtonItem) {
let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .PhotoLibrary
imagePickerController.delegate = self
imagePickerController.mediaTypes = ["public.image", "public.movie"]
presentViewController(imagePickerController, animated: true, completion: nil)
}
Actually you can get the answers from the Apple Document:
UIImagePickerController Class Reference
The useful method is class func availableMediaTypesForSourceType.
You can try this:
let types = UIImagePickerController.availableMediaTypesForSourceType(.PhotoLibrary)
print(types)
Then you know videos types are named public.movie , not kUTTypeMovie anymore.

Resources