如何检查用户是否已授予Multipeer Connectivity设备连接权限?
我在使用iOS的Multipeer Connectivity框架开发时,编写了如下Connector类代码:
class Connector : NSObject, ObservableObject { @Published var peers = [MCPeerID]() @Published var event: String? private let serviceType = "app" private let peerId = MCPeerID(displayName: UIDevice.current.name) private let serviceAdvertiser: MCNearbyServiceAdvertiser private let serviceBrowser: MCNearbyServiceBrowser private let session: MCSession private let log = Logger() override init() { session = MCSession(peer: peerId, securityIdentity: nil, encryptionPreference: .none) serviceAdvertiser = MCNearbyServiceAdvertiser(peer: peerId, discoveryInfo: ["event" : "hello"], serviceType: serviceType) serviceBrowser = MCNearbyServiceBrowser(peer: peerId, serviceType: serviceType) super.init() session.delegate = self serviceAdvertiser.delegate = self serviceBrowser.delegate = self serviceAdvertiser.startAdvertisingPeer() serviceBrowser.startBrowsingForPeers() } deinit { serviceAdvertiser.stopAdvertisingPeer() serviceBrowser.stopBrowsingForPeers() } } extension Connector : MCNearbyServiceAdvertiserDelegate { func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) { log.error("ServiceAdvertiser didNotStartAdvertisingPeer: \(String(describing: error))") } func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) { log.info("didReceiveInvitationFromPeer \(peerID)") } } // 其他基础代理实现...
首次创建Connector对象时,iOS会弹出权限请求弹窗,询问用户是否允许查找并连接其他设备(已配置Info.plist中的隐私文本)。但点击“不允许”时,advertiser(_:didNotStartAdvertisingPeer:)代理方法并未被调用,且我未找到iOS API可在后续(如应用重启后)查询用户的权限选择状态。请问是否存在类似摄像头、位置权限的查询方式来获取用户的权限选择状态?
回答
Multipeer Connectivity 依赖iOS的本地网络权限(Local Network Access),但系统并未提供像摄像头、位置权限那样的直接查询API。不过可以通过以下两种方式间接判断权限状态:
通过服务启动的错误回调推断:
当用户拒绝本地网络权限时,MCNearbyServiceBrowser的browser(_:didNotStartBrowsingForPeers:)代理方法会收到MCError(code: .peerNotConnectedToNetwork)错误;而MCNearbyServiceAdvertiser的对应错误回调可能不会触发,因此可以结合浏览器的错误状态来推断权限是否被拒绝。引导用户前往设置修改权限:
如果无法通过回调明确判断,可提示用户前往应用设置页面开启本地网络权限,通过以下代码跳转至设置页:if let settingsURL = URL(string: UIApplication.openSettingsURLString) { UIApplication.shared.open(settingsURL) }
需要注意:本地网络权限的请求弹窗仅在首次触发时出现,后续用户只能通过系统设置修改权限。若用户已拒绝权限,再次启动广告或浏览服务不会重复弹窗,也不会触发广告服务的错误回调,但浏览器的错误回调会正常触发。
内容的提问来源于stack exchange,提问作者meaning-matters

