设置 MCSessionDelegate 时,MultiPeer Connectivity 不会连接

MultiPeer Connectivity won't connect when MCSessionDelegate is set

我正在开发一个需要多点连接的应用程序,并且 运行 遇到了一个特殊问题。

如果我设置了 MCSessionDelegate,我的设备将无法连接。如果我不设置 MCSession 委托我的设备连接,但我无法收到响应。

没有代表我可以知道他们正在连接,因为打印出 MCSession.connectedPeers 数组显示了其他对等方。

处理连接和通信的 class 的简化版本如下所示。

import UIKit
import MultipeerConnectivity

class ConnectionManager: NSObject, MCSessionDelegate, MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate {

    // MARK: - Properties

    var advertiser: MCNearbyServiceAdvertiser!
    var browser: MCNearbyServiceBrowser!
    var peerID: MCPeerID!
    var session: MCSession!

    // MARK: - Lifecycle

    override init() {
        super.init()
        peerID = MCPeerID(displayName: UIDevice.current.name)


        advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "testconnect")
        advertiser.delegate = self

        browser = MCNearbyServiceBrowser(peer: peerID, serviceType: "testconnect")
        browser.delegate = self

        session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .optional)
        session.delegate = self
    }

    deinit {
        advertiser.stopAdvertisingPeer()
        browser.stopBrowsingForPeers()
        print("Stopping connection service...")
    }

    // MARK: Session Delegate

    func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
    }

    func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
        switch state {
        case .connected:
            print("\(peerID.displayName) connected")
        case .notConnected:
            print("\(peerID.displayName) not connected")
        case .connecting:
            print("\(peerID.displayName) connecting")
        }
    }

    func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {

    }

    func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {

    }

    func session(_ session: MCSession, didReceiveCertificate certificate: [Any]?, fromPeer peerID: MCPeerID, certificateHandler: @escaping (Bool) -> Void) {

    }

    func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {

    }

    // MARK: - Nearby Advertiser Delegate

    func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) {
        print("\(#function): \(error.localizedDescription)")
    }

    func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
        print("Invitation received from \(peerID.displayName)")
        invitationHandler(true, session)
    }

    // MARK: - Nearby Browser Delegate

    func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
        print("Lost peer \(peerID.displayName)")
    }

    func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) {
        print(error.localizedDescription)
    }

    func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String: String]?) {
        print("Found peer \(peerID.displayName)")
        browser.invitePeer(peerID, to: session, withContext: nil,    timeout: 30)
    }
}

如果我注释掉设备连接的 session.delegate = self 行,如打印 session.connectedPeers 所示。保持原样,设备尝试连接,但失败。

我还创建了一个非常简单的应用程序来演示这里的问题,https://github.com/StagasaurusRex/MultiPeerConnectionTest

只需让两台设备都做广告,然后让其中一台设备浏览,设备将尝试连接,您可以看到使用代理失败但没有代理则成功。通过打印连接来验证这一点。

有谁知道发生了什么事吗?我将非常感谢您的帮助,我一直在绞尽脑汁想弄明白。

谢谢。

好吧,我想通了。

我有一个空的 session(_:didReceiveCertificate:fromPeer:certificateHandler:) 实现,它拒绝连接,因为它没有用 true 调用 certificateHandler。

删除空函数解决了我的问题并允许我的设备连接。