Skip to content

Instantly share code, notes, and snippets.

@theisegeberg
Last active December 29, 2021 17:00
Show Gist options
  • Save theisegeberg/db3b2138f3c290e5ead9a4157a4f3c3c to your computer and use it in GitHub Desktop.
Save theisegeberg/db3b2138f3c290e5ead9a4157a4f3c3c to your computer and use it in GitHub Desktop.
MultiPeerConnectivity example (tested working in iOS 12, device + simulator)
import Foundation
import MultipeerConnectivity
class MCSessionAdapter:NSObject,MCSessionDelegate {
var session:MCSession?
weak var delegate:PeerSessionDelegate?
func setSession(_ session:MCSession) {
self.session = session
session.delegate = self
}
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case .connecting:
self.delegate?.peerConnecting(peerID: peerID)
case .connected:
self.delegate?.peerConnected(peerID: peerID)
case .notConnected:
self.delegate?.peerDisconnected(peerID: peerID)
}
}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
self.delegate?.peerReceived(data: data, from: peerID)
}
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?) {
}
}
import Foundation
import MultipeerConnectivity
class PeerClientSession:NSObject,PeerConnection,MCNearbyServiceAdvertiserDelegate {
enum Error:Swift.Error {
case noSession
}
let mcSession:MCSession
var advertiser:MCNearbyServiceAdvertiser?
let peerId:MCPeerID
unowned let delegate:PeerSessionDelegate
var sessionHandler:MCSessionAdapter?
required init(displayName: String, delegate: PeerSessionDelegate) {
self.delegate = delegate
let peerdId = MCPeerID(displayName: displayName)
self.peerId = peerdId
let session = MCSession(peer: peerId, securityIdentity: nil, encryptionPreference: MCEncryptionPreference.none)
self.mcSession = session
super.init()
}
func connect() {
self.disconnect()
let sessionHandler = MCSessionAdapter()
sessionHandler.setSession(self.mcSession)
sessionHandler.delegate = self.delegate
self.sessionHandler = sessionHandler
let advertiser = MCNearbyServiceAdvertiser(peer: self.peerId, discoveryInfo: nil, serviceType: peerServiceType)
advertiser.delegate = self
self.advertiser = advertiser
advertiser.startAdvertisingPeer()
}
func disconnect() {
self.advertiser?.stopAdvertisingPeer()
self.mcSession.disconnect()
self.sessionHandler = nil
self.mcSession.disconnect()
self.delegate.connectionClosed()
}
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Swift.Error) {
self.delegate.peerConnectionError(error)
}
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
invitationHandler(true,self.mcSession)
self.delegate.invitationReceived(from: peerID)
}
}
import Foundation
import MultipeerConnectivity
class PeerHostSession:NSObject,PeerConnection,MCNearbyServiceBrowserDelegate {
let mcSession:MCSession
let peerId:MCPeerID
var browser:MCNearbyServiceBrowser?
let timeout:TimeInterval = 30.0
let sessionHandler:MCSessionAdapter
unowned let delegate:PeerSessionDelegate
required init(displayName: String, delegate: PeerSessionDelegate) {
let peerId = MCPeerID(displayName: displayName)
self.peerId = peerId
self.delegate = delegate
self.mcSession = MCSession(peer: peerId, securityIdentity: nil, encryptionPreference: MCEncryptionPreference.none)
let sessionHandler = MCSessionAdapter()
sessionHandler.setSession(self.mcSession)
sessionHandler.delegate = delegate
self.sessionHandler = sessionHandler
super.init()
}
func connect() {
self.disconnect()
let browser = MCNearbyServiceBrowser(peer: self.peerId, serviceType: peerServiceType)
self.browser = browser
browser.delegate = self
browser.startBrowsingForPeers()
self.delegate.connectionReady()
}
func disconnect() {
self.browser?.stopBrowsingForPeers()
self.browser = nil
self.delegate.connectionClosed()
}
func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
self.delegate.peerDiscovered(peerID: peerID)
browser.invitePeer(peerID, to: self.mcSession, withContext: nil, timeout: self.timeout)
}
func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
self.delegate.peerLost(peerID: peerID)
}
func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) {
self.delegate.peerConnectionError(error)
}
}
import Foundation
import MultipeerConnectivity
protocol PeerConnection {
var mcSession:MCSession { get }
var delegate:PeerSessionDelegate { get }
init(displayName:String,delegate:PeerSessionDelegate)
func connect()
func disconnect()
func send(data:Data)
func send(data:Data,to peerIDs:[MCPeerID])
}
extension PeerConnection {
func send(data: Data) {
self.send(data: data, to: self.mcSession.connectedPeers)
}
func send(data: Data, to peerIDs: [MCPeerID]) {
do {
try self.mcSession.send(data, toPeers: peerIDs, with: MCSessionSendDataMode.reliable)
} catch let error {
self.delegate.peerConnectionError(error)
}
}
}
let peerServiceType = "ttemsctoy"
import Foundation
import MultipeerConnectivity
protocol PeerSessionDelegate:AnyObject {
func peerConnected(peerID:MCPeerID)
func peerConnecting(peerID:MCPeerID)
func peerDisconnected(peerID:MCPeerID)
func peerDiscovered(peerID:MCPeerID)
func peerLost(peerID:MCPeerID)
func peerReceived(data:Data,from peerID:MCPeerID)
func peerConnectionError(_ error:Error)
func connectionReady()
func connectionClosed()
func invitationReceived(from peerID:MCPeerID)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment