MCSessionState 从连接状态变为未连接状态
MCSessionState changes from connecting to not connected state
每当我尝试使用 Multipeer Connectivity Framework 连接对等点时,对等点的状态就会从 MCSessionState.Connecting
更改为 MCSessionState.NotConnected
。
这是我运行的事件顺序:
- 模拟器通过 MCNearbyServiceAdvertiser.
广告服务
- iPhone 通过 MCNearbyServiceBrowser 浏览服务。
- iPhone 找到模拟器并立即邀请它加入
session 通过 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"
}
}
}
有一个类似的,但是链接的代码是旧的,不能再访问了。此外,问题是使用了相同的 session object。
我为 MCSession、MCNearbyServiceAdvertiser 和 MCNearbyServiceBrowser 使用了不同的 MCPeerID 实例。
为了修复它,我创建了一个 MCPeerID 实例变量:
var localPeerID: MCPeerID?
override func viewDidLoad() {
// ...
localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
// ...
}
... 并使用它而不是将它们创建为局部变量 (let localPeerID = ...
)。
它现在从 connecting 状态正确地变为 connected 状态。
始终可以将其创建为 class!
的常量
class ViewController: UIViewController {
var advertiser: MCNearbyServiceAdvertiser!
var browser: MCNearbyServiceBrowser!
var session: MCSession!
let localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
...
}
每当我尝试使用 Multipeer Connectivity Framework 连接对等点时,对等点的状态就会从 MCSessionState.Connecting
更改为 MCSessionState.NotConnected
。
这是我运行的事件顺序:
- 模拟器通过 MCNearbyServiceAdvertiser. 广告服务
- iPhone 通过 MCNearbyServiceBrowser 浏览服务。
- iPhone 找到模拟器并立即邀请它加入 session 通过 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"
}
}
}
有一个类似的
我为 MCSession、MCNearbyServiceAdvertiser 和 MCNearbyServiceBrowser 使用了不同的 MCPeerID 实例。
为了修复它,我创建了一个 MCPeerID 实例变量:
var localPeerID: MCPeerID?
override func viewDidLoad() {
// ...
localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
// ...
}
... 并使用它而不是将它们创建为局部变量 (let localPeerID = ...
)。
它现在从 connecting 状态正确地变为 connected 状态。
始终可以将其创建为 class!
的常量class ViewController: UIViewController {
var advertiser: MCNearbyServiceAdvertiser!
var browser: MCNearbyServiceBrowser!
var session: MCSession!
let localPeerID = MCPeerID(displayName: UIDevice.currentDevice().name)
...
}