在嵌套函数中返回bool

时间:2016-11-12 19:17:15

标签: ios swift

我想请求一些权限,并希望返回false,除非已授予所有权限。 我收到一个错误: " void函数"

中出现意外的非void返回值

但我在所有情况下都返回真/假,出了什么问题?

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")
        }
    })
}

非常感谢任何帮助!谢谢。

  

替代答案:

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)
            }
        })
    })
}

2 个答案:

答案 0 :(得分:1)

问题是,关闭return关键字内部与requestPermissions()函数的返回无关。它意味着从闭包返回,它实际上没有返回任何东西(因为-> Void部分)

您可以将带有三个bool参数的闭包传递给您的函数,如下所示:

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)
        }
    })
}

用法:

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

请注意,我也删除了DispatchQueue.main.async,因为这里没有任何意义。同样,return表示 return from the current scope ,而不是来自外部函数。

修改

需要注意的另一点是,如果视频权限遭到拒绝,您的代码就不会要求获得音频和通知权限。不确定它是否是故意的。 如果事实上你需要独立请求所有这三件事,我认为这是你的情况,你应该使用类似的方法:

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)
    }
}

基本上,只要您完成上一个操作,就会立即要求下一个操作,并且无论先前请求的选择是什么,都会独立请求下一个操作。

答案 1 :(得分:1)

你试图在completionHandler块中返回Bool值,这是返回类型void,你可能显然知道什么都不应该被返回!!!

这就是您遇到此错误的原因“void函数中出现意外的非空返回值”