Topics

#63: Multipeer Connectivity Basics 👪

Topics

The Multipeer Connectivity framework allows devices to communicate directly with one another without the need for a central server. It uses all sorts of technology under the hood: Peer-to-peer WiFi, "regular" WiFi, as well as Bluetooth. It can handle all kinds of data: streams, files, or just good 'ol NSData. Let's try it out. First we need a service type, here's ours (just a global variable):

let CrewChatServiceType = "crew-chat"

When a user wants to start a new chat session, we need to advertise it to other nearby devices, we can do that with an MCNearbyServiceAdvertiser:

let serviceAdvertiser = MCNearbyServiceAdvertiser(
  peer: localPeerID,
  discoveryInfo: nil,
  serviceType: CrewChatServiceType
)

serviceAdvertiser.delegate = self
serviceAdvertiser.startAdvertisingPeer()

Next, we need to properly respond to invitations from other peers. To do this we'll need to implement just one (very verbosely named) function. It is
advertiser(advertiser:didRecieveInvitationFromPeer:withContent:invitationHandler:).

We'll create a session, then pass it to the provided handler.

func advertiser(advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: NSData?, invitationHandler: (Bool, MCSession) -> Void) {
  let session = MCSession(
    peer: localPeerID,
    securityIdentity: nil,
    encryptionPreference: .None
  )

  session.delegate = self

  invitationHandler(true, session)
}

Lastly, we'll test things out by sending new peers a welcome message after they connect, using the session delegate's session(session:peer:didChangeState:) function:

func session(session: MCSession, peer peerID: MCPeerID, didChangeState state: MCSessionState) {
  if state == MCSessionState.Connected {
    let message = "Hello \(peerID.displayName), welcome to the chat!"
    let messageData = message.dataUsingEncoding(NSUTF8StringEncoding)!

    try! session.sendData(messageData, toPeers: [peerID], withMode: .Reliable)
  }
}