Skip to content

Instantly share code, notes, and snippets.

@lucasecf
Last active February 24, 2023 23:16
Show Gist options
  • Save lucasecf/bde1d9bd3492f29b7534 to your computer and use it in GitHub Desktop.
Save lucasecf/bde1d9bd3492f29b7534 to your computer and use it in GitHub Desktop.
Example of how to use the streaming feature of the iOS MultipeerConnectivity framework
/*
For this Gist, we have two sides: sender and receiver. The same user can be a sender and a receiver, but I will separate this
two roles to be more clear.
This gist assumes thatyou already have a MCSession created, and the peers are connected,
*/
//First, we are in the sender side. We need to have a NSOutputStream property, in order to send data to the receiver.
var outputStream:NSOutputStream?
//Somewhere, schedule the stream in the mainRunLoop, set the delegate and open it. Choose the peer that you want to connect.
var err:NSError? = nil
outputStream = session.startStreamWithName("chat", toPeer: session.connectedPeers.first as MCPeerID, error:&err)
if let outputStream = outputStream {
outputStream.delegate = self
outputStream.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
outputStream.open()
}
/*
On the receiver side, the application will call the MCSessionDelegate. Receive the stream, schedule in the mainRunLoop too and open it.
Optionally check if the received stream is the one you want with the streamName parameter
*/
func session(session: MCSession!, didReceiveStream stream: NSInputStream!, withName streamName: String!, fromPeer peerID: MCPeerID!) {
stream.delegate = self
stream.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
stream.open()
}
//After the two streams are opened, on the sender side, you can write the data with the code below:
let message = "This is a string test"
let data = NSKeyedArchiver.archivedDataWithRootObject(message) //this is a NSData instance. Could be any NSData, as a serialized object, for example.
//write in the output stream the bytes array of the NSData
if let output = output {
output.write(UnsafePointer(data.bytes), maxLength: data.length)
}
//Now, again on the receiver side, you need to implement the NSStreamDelegate delegate, and the method below. This method will be called when the output writes any data to the input
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
switch(eventCode){
case NSStreamEvent.HasBytesAvailable:
let input = aStream as NSInputStream
var buffer = [UInt8](count: 1024, repeatedValue: 0) //allocate a buffer. The size of the buffer will depended on the size of the data you are sending.
let numberBytes = input.read(&buffer, maxLength:1024)
let dataString = NSData(bytes: &buffer, length: numberBytes)
let message = NSKeyedUnarchiver.unarchiveObjectWithData(dataString) as String //deserializing the NSData
//input
case NSStreamEvent.HasSpaceAvailable:
break
//output
default:
break
}
}
//Now message will hold the sent "This is a string test"!
@Yang-Xijie
Copy link

The full example using both Data and Stream. (Swift 5, Xcode 13, iOS 15)

https://github.com/Yang-Xijie/ExPeerMessage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment