简体   繁体   中英

Multipeer Connectivity how to get the name of the advertising peer?

iOS12 Swift 5.x

I using Multipeer Connectivity. So far it works well, if I connect my devices in the correct order.

Using boiler plate code, tracked down the problem to here.

func setupStream() {
  do {
    outputStream = try session.startStream(withName: "chat", toPeer: session.connectedPeers.first!)
    for debug in session.connectedPeers {
      print("Peer connected \(debug.displayName)")
    }
  } catch {
      print("unable to open stream")
  }
  if let outputStream = outputStream {
    outputStream.delegate = self
    outputStream.schedule(in: RunLoop.main, forMode:RunLoop.Mode.default)
    outputStream.open()
  }
}

Now if I start the advertiser first, and then the browsers... it works well, very well. But if I start the browsers BEFORE the advertiser, they seem to see each other... even if I am not advertising from them and the service from them and connect to the wrong client.

How to say connect to the peer adverting the service and not anybody and everybody you find...

iOS 12, Swift 5

Found a solution which I post here, a nice simple one. When I advertised the service I do so with some discovery info. The key here, the discover variable.

Block looks this.

class ColorService : NSObject {

lazy var session : MCSession = {
    let session = MCSession(peer: self.myPeerId, securityIdentity: nil, encryptionPreference: .required)
    session.delegate = self
    return session
}()

 var delegate : ColorServiceDelegate?

// Service type must be a unique string, at most 15 characters long
// and can contain only ASCII lowercase letters, numbers and hyphens.
private let ColorServiceType = "example-color"
private let myPeerId = MCPeerID(displayName: UIDevice.current.name)
private let serviceAdvertiser : MCNearbyServiceAdvertiser

override init() {
    let discover:[String:String] = ["prime":myPeerId.displayName]
    self.serviceAdvertiser = MCNearbyServiceAdvertiser(peer: myPeerId, discoveryInfo: discover, serviceType: ColorServiceType)

    super.init()

    self.serviceAdvertiser.delegate = self
    self.serviceAdvertiser.startAdvertisingPeer()

}

deinit {
    self.serviceAdvertiser.stopAdvertisingPeer()
}

func stopAdvertising() {
  self.serviceAdvertiser.stopAdvertisingPeer()
}

On the other side, when I am looking for the service, I only invite peers who have the discovering set, obviously using said info as the peer to invite.

extension ColorSearch : MCNearbyServiceBrowserDelegate {

func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) {
    NSLog("%@", "didNotStartBrowsingForPeers: \(error)")
}

func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
    NSLog("%@", "foundPeer: \(peerID)")
    NSLog("%@", "invitePeer: \(peerID)")
    NSLog("%@", "discoverInfo: \(info)")
    primePeer = info!["prime"]
    if primePeer != nil {
      if peerID.displayName == primePeer {
        browser.invitePeer(peerID, to: self.session, withContext: nil, timeout: 10)
      }
    }

}

func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
    NSLog("%@", "lostPeer: \(peerID)")
}

func disconnect() {
  self.session.disconnect()
}

And I don't get a matrix of connections, I get a single master and a bunch of slaves. Maybe not what multipeerconnectivity was intended, but a good solution never the less.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM