You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检查用户是否已授予Multipeer Connectivity设备连接权限?

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:30:48