Reading the documentation on InputStream it seems like it should be a matter of setting a delegate on the InputStream, scheduling the InputStream, and calling open to start events firing, but it seems like this doesn't happen without calling run on RunLoop.current, which then runs without returning.
How do I allow the run call to return?
Here is my sample code:
import Foundation
let data : Data = "this is a test".data(using: String.Encoding.utf8)!
let inputStream : InputStream = InputStream(data: data)
class TestStreamDelegate: NSObject, StreamDelegate {
static let CAPACITY = 8 * 1024
let inputStream : InputStream
var buffer : UnsafeMutablePointer<UInt8>
init(inputStream: InputStream) {
self.inputStream = inputStream
self.buffer = UnsafeMutablePointer
.allocate(capacity: TestStreamDelegate.CAPACITY)
}
public func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch (eventCode) {
case Stream.Event.openCompleted:
break
case Stream.Event.hasBytesAvailable:
if aStream == inputStream {
let read = inputStream.read(self.buffer,
maxLength: TestStreamDelegate.CAPACITY)
let str =
String(bytesNoCopy: UnsafeMutableRawPointer(self.buffer),
length: read,
encoding: String.Encoding.utf8,
freeWhenDone: false)
print(str!)
}
case Stream.Event.hasSpaceAvailable:
break
case Stream.Event.errorOccurred:
break
case Stream.Event.endEncountered:
if aStream == inputStream {
inputStream.close()
inputStream.remove(from: RunLoop.current,
forMode: RunLoopMode.defaultRunLoopMode)
}
default:
print("Received \(eventCode.rawValue)")
}
}
}
var testDelegate = TestStreamDelegate(inputStream: inputStream)
inputStream.delegate = testDelegate
inputStream.schedule(in: .current, forMode: .defaultRunLoopMode)
inputStream.open()
RunLoop.current.run()
// Following line never executes:
print("Finished")