
Getting Started with Multipeer Connectivity in Swift
Learn the basics of the Multipeer Connectivity framework.
When we need to establish a connection between nearby devices without relying on an internet connection, we can use the Multipeer Connectivity framework.
This framework allows us to discover services advertised by other devices and exchange information in various ways through peer-to-peer connections using Wi-Fi, Bluetooth, or peer discovery without an internet connection.
For implementing this functionality within your app, you need to configure some permissions in the Info.plist
:
NSLocalNetworkUsageDescription
: indicates that the app needs access to the local network.NSBonjourServices
: lists the Bonjour services that will be advertised and discovered.
Each device in a session process needs a unique identity, represented by an MCPeerID
. A name visible to other peers in displayName
will return something like "Gabriel's iPhone."
To ensure that only devices using the same service connect, use serviceID
, a unique identifier for the service that peers advertise or search for. It must be a maximum of 15 characters and contain only lowercase letters, numbers, and hyphens.
private let peerID = MCPeerID(displayName: UIDevice.current.name)
private let serviceID = "demo-start"
The MCSession
class enables and manages communication between all peers in a multipeer connectivity session. So, of the required parameters, securityIdentity: nil
means we are not using custom certificates, and encryptionPreference: .required
ensures that all transmitted data is encrypted. Complement with the MCSessionDelegate
protocol to monitor state changes and receive data.
private var session: MCSession
session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
session.delegate = self
To provide a user interface for handling invitations from your app, use MCAdvertiserAssistant
. It displays prompts to automatically accept or reject connections.
The application will require the discoveryInfo
parameter, which may contain additional data about the peer, such as device type or app version.
assistant = MCAdvertiserAssistant(serviceType: serviceID, discoveryInfo: nil, session: session)
assistant?.start()
The MCBrowserViewController
class is the essential interface for browsing and connecting to advertising peers. It displays nearby devices and allows the user to invite them to a session. This displays a list of nearby devices advertising the same service ID. In addition, the MCBrowserViewControllerDelegate
delegate handles screen cancellation events.
let browser = MCBrowserViewController(serviceType: serviceID, session: session)
browser.delegate = self
There are also some mandatory protocols that monitor events within the session. For example, didChange state
is useful for knowing when a peer connects, disconnects, or is trying to connect. Other mandatory methods that may remain empty because they are not initially needed are didReceive data
, didReceive stream
, didStartReceivingResourceWithName
, and didFinishReceivingResourceWithName
.
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {}
func session(_ session: MCSession,
didReceive stream: InputStream,
withName streamName: String,
fromPeer peerID: MCPeerID) {}
func session(_ session: MCSession,
didStartReceivingResourceWithName resourceName: String,
fromPeer peerID: MCPeerID,
with progress: Progress) {}
func session(_ session: MCSession,
didFinishReceivingResourceWithName resourceName: String,
fromPeer peerID: MCPeerID,
at localURL: URL?,
withError error: Error?) {}
Finally, to allow the user to actually end or cancel the search, use properties of the MCBrowserViewControllerDelegate
protocol that control user interaction with the browser.
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController)
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController)
This is the main point to get started with the Multipeer Connectivity
framework, enough for two nearby devices to find and connect. I also leave a suggestion to cover all the code presented:
import Foundation
import MultipeerConnectivity
class PeerHandler: NSObject, ObservableObject {
private let serviceID = "demo-start"
private let peerID = MCPeerID(displayName: UIDevice.current.name)
private var session: MCSession
private var assistant: MCAdvertiserAssistant?
override init() {
session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
super.init()
session.delegate = self
}
func startHosting() {
assistant = MCAdvertiserAssistant(serviceType: serviceID, discoveryInfo: nil, session: session)
assistant?.start()
}
func makeBrowser() -> MCBrowserViewController {
let browser = MCBrowserViewController(serviceType: serviceID, session: session)
browser.delegate = self
return browser
}
}
extension PeerHandler: MCSessionDelegate {
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {}
func session(_ session: MCSession,
didReceive stream: InputStream,
withName streamName: String,
fromPeer peerID: MCPeerID) {}
func session(_ session: MCSession,
didStartReceivingResourceWithName resourceName: String,
fromPeer peerID: MCPeerID,
with progress: Progress) {}
func session(_ session: MCSession,
didFinishReceivingResourceWithName resourceName: String,
fromPeer peerID: MCPeerID,
at localURL: URL?,
withError error: Error?) {}
}
extension PeerHandler: MCBrowserViewControllerDelegate {
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true)
}
}