Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning bool in nested function

Tags:

ios

swift

I want to request some permissions and want to return false unless all permissions have been granted. I get an error: "Unexpected non-void return value in void function"

But I am returning true/false in all circumstances, what is wrong ?

func requestPermissions () -> Bool {
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)
    let center = UNUserNotificationCenter.current()

    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
        if (videoGranted) {
            AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler: { (audioGranted: Bool) -> Void in
                if (audioGranted) {
                    center.requestAuthorization(options: [.alert, .badge, .sound]) { (notificationGranted:Bool, error) -> Void in
                        if (notificationGranted) {
                            DispatchQueue.main.async {

                                return true
                                print("Video, audio & notifications granted")
                            }
                        } else {

                            return false
                            print("Rejected notifications")
                        }
                    }
                }else {

                    return false
                    print("Rejected audio")
                }
            })
        } else {

            return false
            print("Rejected video")
        }
    })
}

Any help would be very much appreciated ! Thank you.

Alternative Answer:

func requestPermissionss (completion: ((Bool, Bool, Bool)->Void)?) {
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)
    let center = UNUserNotificationCenter.current()

    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
        AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler: { (audioGranted: Bool) -> Void in
            center.requestAuthorization(options: [.alert, .badge, .sound]) { (notificationGranted:Bool, error) -> Void in
                completion?(videoGranted, audioGranted, notificationGranted)
            }
        })
    })
}
like image 968
KML Avatar asked Mar 09 '26 23:03

KML


1 Answers

The issue is that inside the closure return keyword has nothing to do with the return of requestPermissions() function. It rather means return from the closure, which doesn't actually return anything (because of the -> Void part)

You can pass a closure with three bool parameters to your function like this:

func requestPermissions (completion: ((Bool, Bool, Bool)->Void)?) {
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)
    let center = UNUserNotificationCenter.current()

    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
        if (videoGranted) {
            AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler: { (audioGranted: Bool) -> Void in
                if (audioGranted) {
                    center.requestAuthorization(options: [.alert, .badge, .sound]) { (notificationGranted:Bool, error) -> Void in
                        if (notificationGranted) {
                            completion?(true, true, true)
                        } else {
                            completion?(true, true, false)
                        }
                    }
                }else {
                    completion?(true, false, false)
                }
            })
        } else {
            completion?(false, false, false)
        }
    })
}

Usage:

requestPermissions { (videoGranted, audioGranted, notificationsGranted) in
    print("video granted: \(videoGranted)")
    print("audio granted: \(audioGranted)")
    print("notifications granted: \(notificationsGranted)")
}

Note, that I also removed DispatchQueue.main.async because it has no sense here. Again, return means return from the current scope, not from the outer function.

Edit

Another thing to note is that with your code you won't ask permissions for audio and notifications if permission for video was declined. Not sure if it is intentional or not. If in fact you need to request all three things independently, which I suppose is your case, you should use approach similar to this:

func requestPermissions() {
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)

    self.requestVideo { videoGranted in
        print("video granted: \(videoGranted)")
        self.requestAudio { audioGranted in
            print("audio granted: \(audioGranted)")
            self.requestNotifications { notificationsGranted in
                print("notification granted: \(notificationsGranted)")
            }
        }
    }
}


func requestVideo (completion: ((Bool)->Void)?) {
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
        completion?(videoGranted)
    })
}

func requestAudio (completion: ((Bool)->Void)?) {
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler: { (audioGranted: Bool) -> Void in
        completion?(audioGranted)
    })
}

func requestNotifications (completion: ((Bool)->Void)?) {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (notificationGranted:Bool, error) -> Void in
        completion?(notificationGranted)
    }
}

Basically you ask for the next thing as soon as you're done with previous one and every next one is requested independently no matter what was the choice on previous requests.

like image 87
alexburtnik Avatar answered Mar 11 '26 13:03

alexburtnik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!