In my application I used camera implementation in that if the user enter very first means that time they choose allow means they have to access camera and photo library in entire application, if it is chosen denied means the user cannot access the camera so that time we need to change camera and photo library in settings.After that we have to access the camera in my case it is not working properly, anyone helps me, much appreciated.
You can check first whether camera permission is allowed or not. If not then you can navigate to settings screen & ask user for permission.
override func viewDidLoad() {
super.viewDidLoad()
checkCameraPermission()
}
func checkCameraPermission() {
let cameraMediaType = AVMediaTypeVideo
AVCaptureDevice.requestAccess(forMediaType: cameraMediaType) { granted in
if granted {
//Do operation
print("Granted access for camera")
self.setCamera()
} else {
self.noCameraFound()
print("Denied access for camera ")
}
}
}
func noCameraFound(){
let alert = UIAlertController(title: "AppName", message: "Please allow camera access in phone settings", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Back", style: UIAlertActionStyle.cancel, handler: {(action:UIAlertAction) in
}));
alert.addAction(UIAlertAction(title: "Open setting ", style: UIAlertActionStyle.default, handler: {(action:UIAlertAction) in
UIApplication.shared.open(NSURL(string:UIApplicationOpenSettingsURLString)! as URL, options: [:], completionHandler: nil)
}));
self.present(alert, animated: true, completion: nil)
}
Related
After requesting face id permission for an application , we get the apple alert that allow the user to grant or deny the use of this technologie .
My question is :
If the user deny the use of face id , is there any solution to request it again without uninstalling the application .
You can request it again, but not in the same way as the first time. What you can do is when you request for Face ID, you should check on the authorization status, which can either be notDetermined, authorized, denied or restricted.
In the case that it is notDetermined you can bring up the request access that you are already doing, and if it is denied you can give the user the option to go to Settings -> YourAppName to give FaceID access to your app.
Here is an example taken from the following answer: Reference Question
It is for Camera Access but you should be able to apply it to FaceID pretty simply.
#IBAction func goToCamera()
{
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
switch (status) {
case .authorized:
self.popCamera()
case .notDetermined:
AVCaptureDevice.requestAccess(for: AVMediaType.video) { (granted) in
if (granted) {
self.popCamera()
} else {
self.camDenied()
}
}
case .denied:
self.camDenied()
case .restricted:
let alert = UIAlertController(title: "Restricted",
message: "You've been restricted from using the camera on this device. Without camera access this feature won't work. Please contact the device owner so they can give you access.",
preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
Then in the camDenied function:
func camDenied() {
DispatchQueue.main.async {
var alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:\n\n1. Close this app.\n\n2. Open the Settings app.\n\n3. Scroll to the bottom and select this app in the list.\n\n4. Turn the Camera on.\n\n5. Open this app and try again."
var alertButton = "OK"
var goAction = UIAlertAction(title: alertButton, style: .default, handler: nil)
if UIApplication.shared.canOpenURL(URL(string: UIApplicationOpenSettingsURLString)!) {
alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:\n\n1. Touch the Go button below to open the Settings app.\n\n2. Turn the Camera on.\n\n3. Open this app and try again."
alertButton = "Go"
goAction = UIAlertAction(title: alertButton, style: .default, handler: {(alert: UIAlertAction!) -> Void in
UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)
})
}
let alert = UIAlertController(title: "Error", message: alertText, preferredStyle: .alert)
alert.addAction(goAction)
self.present(alert, animated: true, completion: nil)
}
}
I have a button that when tap on it I have to check microphone permission.
For this reason I done this:
public func askMicrophoneAuthorization()
{
recordingSession = AVAudioSession.sharedInstance()
recordingSession.requestRecordPermission() { [unowned self] allowed in
DispatchQueue.main.async {
if allowed
{
self.goToNextStep()
} else
{
self.denied()
}
}
}
}
my problem is this: when I tap on button and askMicrophoneAuthorization method is called, if its the first time that I ask the permission, the microphone system alert, with text inserted in plist file, shows and I can denied or not the permission. If I deny the permission and then I re-tap on button method self.denied() is executed and I dont see the microphone system alert.
Is it possibile to re-show the system-alert?
It's not possible to show the system alert if the user has already denied.
The best you can do is to check the permission and if they're denied show an alert with a button that opens the app settings.
func askPermissionIfNeeded() {
switch AVAudioSession.sharedInstance().recordPermission {
case undetermined:
askMicrophoneAuthorization()
case denied:
let alert = UIAlertController(title: "Error", message: "Please allow microphone usage from settings", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Open settings", style: .default, handler: { action in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
case granted:
goToNextStep()
}
}
In my project I tried to add two things:
A camera source for a person's avatar.
add permission for the camera and photo library access in the info.plist file.
But when I tried to test my app in a real device the app doesn’t show any permission, and when I chose the camera the app exit without error message in the log console?
For the info.plist I use this two line:
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) camera use</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>$(PRODUCT_NAME) photo use</string>
And add a photo I use this code:
#objc func addNewPerson(){
let picker = UIImagePickerController()
let ac = UIAlertController(title: "Choose image", message: nil, preferredStyle: .actionSheet)
let camera = UIAlertAction(title: "Camera", style: .default){
[weak self] _ in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.allowsEditing = false
picker.delegate = self
picker.sourceType = .camera
self?.present(picker,animated: true)
}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)
}
}
ac.addAction(camera)
let galerie = UIAlertAction(title: "Photo library", style: .default){
[weak self] _ in
picker.allowsEditing = true
picker.delegate = self
self?.present(picker,animated: true)
}
ac.addAction(galerie)
ac.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(ac,animated: true)
}
Thank you.
in your addNewPerson() method before showing the alert you should check if the user already granted access to his Camera you can do that by :
if AVCaptureDevice.AVCaptureDevice.authorizationStatus(AVMediaTypeVideo) == AVAuthorizationStatus.Authorized {
// Already Authorized
} else {
AVCaptureDevice. requestAccess(AVMediaTypeVideo, completionHandler: { (granted: Bool) -> Void in
if granted == true {
// User granted
} else {
// User rejected
}
})
}
and before that make sure you added
Just to mention, in iOS 11 camera access is not required to use the UIImagePicker
Here is copy-pasted fragment from rickster's post.
in iOS 11, UIImagePickerController runs as a separate process from your app. That means:
Your app can't see the user's whole Photos library — it gets read-only access just for whichever asset(s) the user chooses in the image picker.
Because of (1), your app doesn't need the standard privacy authorization for Photos library access. The user explicitly chooses a
specific asset (or multiple) for use in your app, which means the user is granting your app permission to read the asset(s) in question.
If user dennied the camera access, i am showing one alert with cancel and setting button to show it. But the code is not working.
#IBAction func ProfileImageButton(_ sender: UIButton) {
print("profile image Button is pressed")
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
profileimgbool = true
let actionSheet = UIAlertController(title: "Photo Source", message: "choose a Source", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action:UIAlertAction) in imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Photo Library", 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 checkCameraPermission() {
let cameraMediaType = AVMediaType.video
AVCaptureDevice.requestAccess(for: cameraMediaType) { granted in
if granted {
//Do operation
print("Granted access for camera")
// self.setCamera()
} else {
self.noCameraFound()
print("Denied access for camera ")
}
}
}
func noCameraFound(){
let alert = UIAlertController(title: "CallDoc", message: "Please allow camera access in phone settings", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Back", style: UIAlertActionStyle.cancel, handler: {(action:UIAlertAction) in
}));
alert.addAction(UIAlertAction(title: "Open setting", style: UIAlertActionStyle.default, handler: {(action:UIAlertAction) in
UIApplication.shared.open(NSURL(string:UIApplicationOpenSettingsURLString)! as URL, options: [:], completionHandler: nil)
}));
self.present(alert, animated: true, completion: nil)
}
in my above code my method was checkCameraPermission where i will call this to show alert. I needs to show when user click camera, and when if user denied that black screen will show instead of camera. There i need to show that alert pop up.
Where i can call this checkCameraPermission method to show my popup ?.
Any idea ?
for reference purpose I taken the answer from this tutorial.
step 1
add the avfoundation framework in your project
import AVFoundation
step 2
dont forget to Set Camera Usage Description in Info.plist
When you request permission to use the device’s camera, a short message will appear in the default iOS system dialog. You customize this message by adding the Privacy - Camera Usage Description key to your Info.plist file.
step 3
on your image profile change button action verify the permission, etc.
#IBAction func ProfileImageButton(_ sender: UIButton) {
let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
switch cameraAuthorizationStatus {
case .notDetermined: requestCameraPermission()
case .authorized: presentCamera()
case .restricted, .denied: alertCameraAccessNeeded()
}
}
based on the above action the condition will satisfy,
If the user has never responded to a request to access his/her camera, you need to prompt with the iOS system alert to request permission:
func requestCameraPermission() {
AVCaptureDevice.requestAccess(for: .video, completionHandler: {accessGranted in
guard accessGranted == true else { return }
self.presentCamera()
})
}
there after the camera access will continue
func presentCamera() {
let photoPicker = UIImagePickerController()
photoPicker.sourceType = .camera
photoPicker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
self.present(photoPicker, animated: true, completion: nil)
}
To use the image that the camera captured, you need to set up your view controller to adhere to and implement couple of delegate protocols:
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
// ...
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let photo = info[UIImagePickerControllerOriginalImage] as! UIImage
// do something with the photo... set to UIImageView, save it, etc.
dismiss(animated: true, completion: nil)
}
If camera access has been denied or restricted, you can alert the user and direct them to the Settings app to make the appropriate permissions adjustment:
func alertCameraAccessNeeded() {
let settingsAppURL = URL(string: UIApplicationOpenSettingsURLString)!
let alert = UIAlertController(
title: "Need Camera Access",
message: "Camera access is required to make full use of this app.",
preferredStyle: UIAlertControllerStyle.alert
)
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel, handler: { (alert) -> Void in
UIApplication.shared.open(settingsAppURL, options: [:], completionHandler: nil)
}))
present(alert, animated: true, completion: nil)
}
Here's the problem:
There are two UIViewControllers: "WelcomeScreen" and, for example, "FailScreen".
There is a Camera Access Request on the first one.
User taps "Don't allow" and FailScreen opens. ...And crashes.
Code:
AVCaptureDevice.requestAccess(for: .video) { (answer: Bool) in
print("Camera access request.")
if answer {
print("Camera access autorized.")
// Continue to Notifications Request...
}
else {
print("Camera access denied.")
self.present(FailureViewController(), animated: true, completion: nil)
}
Console:
Camera access denied.
libc++abi.dylib: terminating with uncaught exception of type NSException
Transition to other ViewController crashes in the same way after Notifications Request (right next to Camera Access Request).
I'm noob. :)
I tried present(VC), show(VC), push(VC). Result is the same.
I'm not using Storyboards. I do everything programmatically.
Yes, I can show FailScreen on the same ViewController, but what about other options to avoid this error?
Can someone tell me, how to fix it? Thank You.
I hope this will help you.
First you should added value for Privacy - Camera Usage Description key in Info.plist and understand below code
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (success) in
if success {
print("The user granted permission")
} else {
print("put up an alert telling the user the camera is not available")
DispatchQueue.main.async(execute: { () -> Void in
let ac = UIAlertController(title: "Camera Error", message: "For some reason, the camera in this device is not accepting your authorization. Check with your device supplier.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(ac, animated: true, completion: nil)
})//back on main queue block
}//if success
})//requestAccessForMediaType block
}//switch
} else {//if device has a camera
let ac = UIAlertController(title: "Source not available.", message: "The camera is not available.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
present(ac, animated: true, completion: nil)
}//if camera is no else
}