Skip to content

Bluetooth or Wifi Networking with Apple's Multipeer Connectivity framework.

License

Notifications You must be signed in to change notification settings

p-sun/iOSMultiplayerTemplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iOSMultiplayerTemplate / P2PKit

P2PKit is a Bluetooth or WiFi Networking framework for hackathons! It is uses Apple's Multipeer Connectivity and works for all iOS, including Vision Pro, iPhone, and iPad.

Features

  • Offline data passing! For best performance across real devices, disable WiFi to use bluetooth connection.
  • Automatic retrying when peers disconnect.
  • Easy APIs for sending/receiving Codable data, with callbacks or with SwiftUI.
  • Game Demo that uses P2PKit.
  • APIs for setting/observing one device as host and the rest as followers.
  • APIs for resetting session, changing the display name, and debugging.

Game Demo

You're the mallet with the star. When the white puck enters a hole, the last person to touch the white puck with their mallet scores a point!

P2PKitDemoPhone.mp4

APIs

3.Data.Passing.mov

Use P2PSynced to sync Codable data

P2PSynced is the easiest way to sync data across devices.

let syncedRoom = P2PSynced<GameRoom>(
        name: "GameRoom",
        initial: GameRoom(),
        writeAccess: .hostOnly, // Optional param. Defaults to .everyone has write access. If using .hostOnly, set host with `P2PNetwork.makeMeHost()`.
        reliable: true) // Optional param. Defaults to false. Reliable sending is slower but preserves order and doesn't drop messages.

// GET data
syncedRoom.onReceiveSync = { gameRoom in }

// SEND DATA
syncedRoom.value = GameRoom(...) 

Use P2PSyncedObservable with Swift UI

Use P2PSyncedObservable, a light wrapper around P2PSynced, with SwiftUI.

In this example, an Int value is sent between devices to sync a counter.

struct SyncedCounter: View {
    @StateObject private var counter = P2PSyncedObservable(name: "SyncedCounter", initial: 1)
    
    var body: some View {
        Button("+ 1") {
            counter.value = counter.value + 1 // SET VALUE
        }
        Text("Counter: \(counter.value)") // RECEIVE VALUE
    }
}

Similarily, in the SyncedCircles example, the Codable object SendableCircle, is synced across all devices.

@StateObject var blueCircle = P2PSyncedObservable(name: "blue", initial: SendableCircle(point: CGPoint(x: 300, y: -26)))
@StateObject var greenCircle = P2PSyncedObservable(name: "green", initial: SendableCircle(point: CGPoint(x: 260, y: -10)))

// RECEIVE
let sendableCircle = blueCircle.value

// SEND
blueCircle.value = SendableCircle(point: newPoint)

Use P2PEventService to send/receive Codable events

let malletDraggedEvents = P2PEventService<MalletDragEvent>("MalletDrag")

// RECEIVE
malletDraggedEvents.onReceive { eventInfo, malletDragEvent, json, sender in
  // Handle malletDragEvent
}

// SEND
malletDraggedEvents.send(payload: MalletDragEvent(...), reliable: false)

P2PNetworkDelegate

Get myself and connected peers.

let myPeer: Peer = P2PNework.myPeer
let connectedPeers: [Peer] = P2PNework.connectedPeers

Observe peer updates with P2PNetworkPeerDelegate. When connectedPeers update, the p2pNetwork(didUpdate peer: Peer) handler will be called.

protocol P2PNetworkPeerDelegate: AnyObject {
    func p2pNetwork(didUpdate peer: Peer)
    func p2pNetwork(didUpdateHost host: Peer?)
}
P2PNework.addPeerDelegate(self)
P2PNework.removePeerDelegate(self)

(Optional) Reset the session.

P2PNework.resetSession("New Display Name") // Change display name.
P2PNework.resetSession(nil) // Keep current display name.

(Optional) Get and set the host for all connected devices. Not all games need a host.

let currentHost: Peer? = P2PNework.host
P2PNework.makeMeHost()

Bonus: Host Features

Host Selection

  • Whoever taps "Create Room" acts as the host server with the game's source of truth, streaming game physics to everyone.
  • Non-hosts disconnect and reconnects automatically, and their score will resume.
  • When a host disconnects, other players get the "Continue Room" button, and the first player to tap that button becomes the host.
  • Any previous host will accept the new host.
2.resume.game.mp4

Host resumes data

When the current device connects to a host, P2PSynced and P2PSyncedObservable will sync the latest data from the host.

4.Host.resumes.data.mp4

About

Bluetooth or Wifi Networking with Apple's Multipeer Connectivity framework.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages