Skip to content

Instantly share code, notes, and snippets.

@muizidn
Created May 8, 2019 06:18
Show Gist options
  • Save muizidn/f62338858e173e86b9d84d3519b85569 to your computer and use it in GitHub Desktop.
Save muizidn/f62338858e173e86b9d84d3519b85569 to your computer and use it in GitHub Desktop.
Implementation of Raywenderlich Tutorial. Use Playground. https://www.raywenderlich.com/537-real-time-communication-with-streams-tutorial-for-ios
import Foundation
class ChatRoom: NSObject, StreamDelegate {
var inputStream: InputStream!
var outputStream: OutputStream!
var username: String = ""
static let maxReadDefault = 4096
func setupNetworkCommunication() {
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(
kCFAllocatorDefault,
"localhost" as CFString,
80,
&readStream,
&writeStream
)
inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()
inputStream.delegate = self
inputStream.schedule(in: .current, forMode: .common)
outputStream.schedule(in: .current, forMode: .common)
inputStream.open()
outputStream.open()
}
func joinChat(username: String) {
let data = "iam:\(username)".data(using: .ascii)!
self.username = username
_ = try? data.withUnsafeBytes({ (pt) throws -> Int in
return outputStream.write(pt, maxLength: data.count)
})
}
func sendMessage(message: String) {
let data = "msg:\(message)".data(using: .ascii)!
_ = data.withUnsafeBytes { outputStream.write($0, maxLength: data.count) }
}
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
case Stream.Event.hasBytesAvailable:
read(stream: aStream as! InputStream)
case Stream.Event.errorOccurred: print("Error")
case Stream.Event.endEncountered: print("End")
case Stream.Event.hasSpaceAvailable: print("Has Space")
default: break
}
}
private func read(stream: InputStream) {
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: ChatRoom.maxReadDefault)
while stream.hasBytesAvailable {
let numberOfBytesRead = inputStream.read(buffer, maxLength: ChatRoom.maxReadDefault)
if numberOfBytesRead < 0 {
if let error = stream.streamError {
print("Stream Error", error)
return
}
}
print(
processMessageString(
buffer,
length: numberOfBytesRead
)
)
}
}
private func processMessageString(_ buffer: UnsafeMutablePointer<UInt8>, length: Int) -> String {
guard let arrayString = String.init(bytesNoCopy: buffer, length: length, encoding: .ascii, freeWhenDone: true)?.components(separatedBy: ":") else {
return "Not a Message"
}
return "\(arrayString.joined(separator: " => "))"
}
}
let room = ChatRoom()
room.setupNetworkCommunication()
room.joinChat(username: "Luke")
room.sendMessage(message: "I am a Skywalker!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment