【问题标题】:Returning bool in nested function在嵌套函数中返回布尔值
【发布时间】:2016-11-12 19:17:15
【问题描述】:

我想请求一些权限并且想要返回 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)
            }
        })
    })
}

【问题讨论】:

  • else { print("Rejected notifications") has no status=true
  • @alldani-com 嗨,我复制了错误的功能,对不起。更新的问题。
  • 在 return 语句之后 swift 是否仍然运行?我知道python没有。
  • 查找“如何从异步函数返回值”
  • 尝试将打印语句放在返回语句之前。

标签: ios swift


【解决方案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)
    }
}

基本上,您在完成上一个请求后立即请求下一个请求,并且无论之前请求的选择是什么,每个下一个请求都是独立请求的。

【讨论】:

  • 我不知道该怎么说,但如果我这样做,函数将自动返回初始化值 (false)。然后在询问所有权限后,它将返回他们给出的任何内容..
【解决方案2】:

您正在尝试在 completionHandler 块中返回 Bool 值,该块的返回类型为 void,您可能显然知道不应该返回任何内容!!!

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2015-02-22
    • 2021-10-29
    • 2013-03-11
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多