Swift MCSessionState从连接状态更改为未连接状态

Swift MCSessionState从连接状态更改为未连接状态,swift,multipeer-connectivity,mcsession,Swift,Multipeer Connectivity,Mcsession,每当我尝试使用连接对等方时,对等方的状态将从MCSessionState.Connecting更改为MCSessionState.NotConnected 以下是我运行的事件顺序: 模拟器通过一个网络广告服务 iPhone通过浏览器浏览该服务 iPhone会找到模拟器,并立即邀请它访问 会议通过 最后,模拟器使用 注: 尽管我不需要安全性,但我接受客户端发送的任何证书 以下是我正在使用的代码: import UIKit import MultipeerConnectivity class

每当我尝试使用连接对等方时,对等方的状态将从
MCSessionState.Connecting
更改为
MCSessionState.NotConnected

以下是我运行的事件顺序:

  • 模拟器通过一个网络广告服务
  • iPhone通过浏览器浏览该服务
  • iPhone会找到模拟器,并立即邀请它访问 会议通过
  • 最后,模拟器使用
  • 注:

    • 尽管我不需要安全性,但我接受客户端发送的任何证书
    以下是我正在使用的代码:

    import UIKit
    import MultipeerConnectivity
    
    class ViewController: UIViewController {
        var advertiser: MCNearbyServiceAdvertiser!
        var browser: MCNearbyServiceBrowser!
        var session: MCSession!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
            session = MCSession(peer: localPeerID, securityIdentity: nil, encryptionPreference: MCEncryptionPreference.None)
            session.delegate = self
        }
    
        @IBAction func hostTapped(sender: AnyObject) {
            let localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
            advertiser = MCNearbyServiceAdvertiser(peer: localPeerID, discoveryInfo: nil, serviceType: "abc")
            advertiser.delegate = self
            print("started advertising")
            advertiser.startAdvertisingPeer()
        }
    
        @IBAction func connectTapped(sender: AnyObject) {
            let localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
            browser = MCNearbyServiceBrowser(peer: localPeerID, serviceType: "abc")
            browser.delegate = self
            print("started searching")
            browser.startBrowsingForPeers()
        }
    }
    
    extension ViewController: MCNearbyServiceAdvertiserDelegate {
        func advertiser(advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: NSData?, invitationHandler: (Bool, MCSession) -> Void) {
            print("accepting invitation from \(peerID.displayName)")
            invitationHandler(true, session)
        }
    
        func advertiser(advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: NSError) {
            print("did not start advertising \(error)")
        }
    }
    
    extension ViewController: MCSessionDelegate {
        func session(session: MCSession, peer peerID: MCPeerID, didChangeState state: MCSessionState) {
            print("\(peerID.displayName) changed state: \(state.toString())")
        }
    
        func session(session: MCSession, didReceiveData data: NSData, fromPeer peerID: MCPeerID) {
    
        }
    
        func session(session: MCSession, didReceiveStream stream: NSInputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
    
        }
    
        func session(session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, withProgress progress: NSProgress) {
    
        }
    
        func session(session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, atURL localURL: NSURL, withError error: NSError?) {
    
        }
    
        func session(session: MCSession, didReceiveCertificate certificate: [AnyObject]?, fromPeer peerID: MCPeerID, certificateHandler: (Bool) -> Void) {
            certificateHandler(true)
        }
    }
    
    extension ViewController: MCNearbyServiceBrowserDelegate {
        func browser(browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
            print("found \(peerID.displayName), inviting to session")
            browser.invitePeer(peerID, toSession: session, withContext: nil, timeout: 30)
        }
    
        func browser(browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
            print("lost \(peerID.displayName)")
        }
    }
    
    extension MCSessionState {
        func toString() -> String {
            switch self {
            case .Connected:    return "Connected"
            case .Connecting:   return "Connecting"
            case .NotConnected: return "Not Connected"
            }
        }
    }
    
    但是,有一个类似的例子,链接的代码很旧,无法再访问。此外,问题在于使用的是同一个会话对象。

    我使用的是不同的MCSession、MCNearbyServiceAdvertiser和MCNearbyServiceBrowser实例

    为了修复它,我创建了一个mcpeirid实例变量:

    var localPeerID: MCPeerID?
    
    override func viewDidLoad() {
        // ...
        localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
        // ...
    }
    
    。。。并使用它而不是将它们创建为局部变量(
    让localPeerID=…


    它现在正确地从连接状态转到连接状态。

    始终可以将其创建为类的常量

    class ViewController: UIViewController {
        var advertiser: MCNearbyServiceAdvertiser!
        var browser: MCNearbyServiceBrowser!
        var session: MCSession!
    
        let localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
        ...
    }
    

    我也有同样的问题。谢谢分享。我个人不喜欢在生产代码中强制展开,除非真的没办法。通过将其设置为常量并在声明点或延迟加载点进行初始化,可以显著提高安全性:)