Home > Enterprise >  How can I get my app to wait for a permission request to complete?
How can I get my app to wait for a permission request to complete?

Time:02-02

Am working on a recording app from scratch and it just has the basics. Within my info.plist I do set Privacy - Microphone Usage Description

Still, I always want to check the "privacy permission" on the microphone because I know people can hit "No" by accident.

However, whatever I try, the app keeps running without waiting for the iOs permission alert to pop up and complete.

    let mediaType = AVMediaType.audio

    let mediaAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: mediaType)
    switch mediaAuthorizationStatus {
        case .denied:
            print (".denied")
        case .authorized:
            print ("authorized")
        case .restricted:
            print ("restricted")

        case .notDetermined:
            print("huh?")

        let myQue = DispatchQueue(label: "get perm")
        myQue.sync 
        {
                AVCaptureDevice.requestAccess(for: .audio, completionHandler: { (granted: Bool) in
                    if granted {
                    } else {
                    }
            })
        }
    default:
        print ("not a clue")
    }

CodePudding user response:

I think you are already on the main thread and trying to DispatchQueue.main.sync from the Main thread. Check it like this.

if Thread.isMainThread {
  // you are already on the main thread
} else {
  DispatchQueue.main.sync {
    // do stuff
  }
}

CodePudding user response:

without waiting for the iOs permission alert to pop up and complete

Great line, partially describing possible solution (imho).

AFAIK all UIAlertController-related routines are richly flavoured with completions. I'd try to put recording logic trigger inside the completion handler of method that presents the alert itself.

CodePudding user response:

Misusing DispatchQueue to force an asynchronous task to become synchronous is a very bad practice.

Either use a completion handler

func avAuthorization(completion : @escaping (Bool) -> Void)
{
    let mediaType = AVMediaType.audio
    let mediaAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: mediaType)
    switch mediaAuthorizationStatus {
        case .denied, .restricted: completion(false)
        case .authorized: completion(true)
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .audio) { granted in
                completion(granted)
            }
    }
}

Or in Swift 5.5 an async function

func avAuthorization() async -> Bool
{
    let mediaType = AVMediaType.audio
    let mediaAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: mediaType)
    switch mediaAuthorizationStatus {
        case .denied, .restricted: return false
        case .authorized: return true
        case .notDetermined: return await AVCaptureDevice.requestAccess(for: .audio)
    }
}
  •  Tags:  
  • Related