首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测iOS 14中是否授予本地网络权限

如何检测iOS 14中是否授予本地网络权限
EN

Stack Overflow用户
提问于 2020-09-25 17:46:33
回答 1查看 3.2K关注 0票数 6

如何检测用户是否已在应用程序中授予iOS 14的本地网络权限?如果用户拒绝了权限并重定向到os设置以授予权限,我必须显示错误屏幕。苹果有没有提供任何方法来找出就像位置许可一样?

EN

回答 1

Stack Overflow用户

发布于 2021-01-29 02:56:12

我编写了这个类,如果您不在iOS 14.2上,可以使用它。

这个类将提示用户获得访问本地网络的权限(第一次)。如果已经denied/granted.,则denied/granted.

  • 验证现有的权限状态。

请记住,这个实例必须保持活动,所以如果在另一个类的函数调用中使用该实例,则需要将该实例保持在调用函数的作用域之外。

代码语言:javascript
复制
import UIKit
import Network

class LocalNetworkPermissionChecker {
    private var host: String
    private var port: UInt16
    private var checkPermissionStatus: DispatchWorkItem?
    
    private lazy var detectDeclineTimer: Timer? = Timer.scheduledTimer(
        withTimeInterval: .zero,
        repeats: false,
        block: { [weak self] _ in
            guard let checkPermissionStatus = self?.checkPermissionStatus else { return }
            DispatchQueue.main.asyncAfter(deadline: .now(), execute: checkPermissionStatus)
        })
    
    init(host: String, port: UInt16, granted: @escaping () -> Void, failure: @escaping (Error?) -> Void) {
        self.host = host
        self.port = port
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(applicationIsInBackground),
            name: UIApplication.willResignActiveNotification,
            object: nil)
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(applicationIsInForeground),
            name: UIApplication.didBecomeActiveNotification,
            object: nil)
        
        actionRequestNetworkPermissions(granted: granted, failure: failure)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    /// Creating a network connection prompts the user for permission to access the local network. We do not have the need to actually send anything over the connection.
    /// - Note: The user will only be prompted once for permission to access the local network. The first time they do this the app will be placed in the background while
    /// the user is being prompted. We check for this to occur. If it does we invalidate our timer and allow the user to make a selection. When the app returns to the foreground
    /// verify what they selected. If this is not the first time they are on this screen, the timer will not be invalidated and we will check the dispatchWorkItem block to see what
    /// their selection was previously.
    /// - Parameters:
    ///   - granted: Informs application that user has provided us with local network permission.
    ///   - failure: Something went awry.
    private func actionRequestNetworkPermissions(granted: @escaping () -> Void, failure: @escaping (Error?) -> Void) {
        guard let port = NWEndpoint.Port(rawValue: port) else { return }
        
        let connection = NWConnection(host: NWEndpoint.Host(host), port: port, using: .udp)
        connection.start(queue: .main)
        
        checkPermissionStatus = DispatchWorkItem(block: { [weak self] in
            if connection.state == .ready {
                self?.detectDeclineTimer?.invalidate()
                granted()
            } else {
                failure(nil)
            }
        })
        
        detectDeclineTimer?.fireDate = Date() + 1
    }
    
    /// Permission prompt will throw the application in to the background and invalidate the timer.
    @objc private func applicationIsInBackground() {
        detectDeclineTimer?.invalidate()
    }
    
    /// - Important: DispatchWorkItem must be called after 1sec otherwise we are calling before the user state is updated.
    @objc private func applicationIsInForeground() {
        guard let checkPermissionStatus = checkPermissionStatus else { return }
        DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: checkPermissionStatus)
    }
}

//Can be used like this:
LocalNetworkPermissionChecker(host: "255.255.255.255", port: 4567, granted: {
    //Perform some action here...
},
failure: { error in
    if let error = error {
        print("Failed with error: \(error.localizedDescription)")
    }
})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64069053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档