我想请求一些权限,并希望返回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)
}
})
})
}
答案 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函数中出现意外的非空返回值”