MCSessionState 从连接状态变为未连接状态

Posted

技术标签:

【中文标题】MCSessionState 从连接状态变为未连接状态【英文标题】:MCSessionState changes from connecting to not connected state 【发布时间】:2015-11-30 21:10:10 【问题描述】:

每当我尝试使用Multipeer Connectivity Framework 连接对等点时,对等点的状态都会从MCSessionState.Connecting 更改为MCSessionState.NotConnected

这是我运行的事件的顺序:

    模拟器通过MCNearbyServiceAdvertiser 宣传该服务。 iPhone 通过MCNearbyServiceBrowser 浏览服务。 iPhone 找到模拟器并立即将其邀请到 会议通过invitePeer(_:toSession:withContext:timeout:)。 最后,模拟器接受邀请使用 advertiser(_:didReceiveInvitationFromPeer:withContext:invitationHandler:)。

注意事项:

即使我不需要安全性,我也接受客户 in case that is the bug 发送的任何证书。

这是我正在使用的代码:

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"
        
    

有一个类似的question here,但是,链接的代码是旧的,无法再访问。此外,问题在于使用了相同的会话对象。

【问题讨论】:

【参考方案1】:

总是可以将它创建为类的常量!

class ViewController: UIViewController 
    var advertiser: MCNearbyServiceAdvertiser!
    var browser: MCNearbyServiceBrowser!
    var session: MCSession!

    let localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
    ...

【讨论】:

【参考方案2】:

我为 MCSession、MCNearbyServiceAdvertiser 和 MCNearbyServiceBrowser 使用了不同的 MCPeerID 实例。

为了解决这个问题,我创建了一个 MCPeerID 实例变量:

var localPeerID: MCPeerID?

override func viewDidLoad() 
    // ...
    localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
    // ...

... 并使用它而不是将它们创建为局部变量 (let localPeerID = ...)。

它现在从 connectingconnected 状态正确。

【讨论】:

我遇到了同样的问题。感谢分享。 个人不喜欢在生产代码中强制展开,除非它真的无能为力。通过将其设置为常量并在声明点或延迟加载时进行初始化,这可以大大提高安全性:)

以上是关于MCSessionState 从连接状态变为未连接状态的主要内容,如果未能解决你的问题,请参考以下文章

为啥Ubuntu连上DSL几分钟之后 有线就会变为 未托管 ?在终端查看网卡状态,已经变为不可用

如何使用 netty 4.0 在连接变为非活动状态后重新连接

在 redux 连接的反应应用程序中未定义初始状态

调用 Reachability startNotifier 后,Network 状态变为 0

Flutter Stateful Widget 状态未初始化

Azure *** 客户端“状态 = *** 平台未触发连接”