I am porting an App from Objective-C to Swift and I need to use the following method:
CFStreamCreatePairWithSocketToHost(alloc: CFAllocator!, host: CFString!, port: UInt32, \ readStream: CMutablePointer<Unmanaged<CFReadStream>?>, \ writeStream: CMutablePointer<Unmanaged<CFWriteStream>?>)
The old logic looks like this (which several web sites seem to agree on):
CFReadStreamRef readStream = NULL; CFWriteStreamRef writeStream = NULL; CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), port, \ &readStream, &writeStream); NSInputStream inputStream = (__bridge_transfer NSInputStream *)readStream; NSOutputStream outputStream = (__bridge_transfer NSOutputStream *)writeStream;
Which works fine thanks to toll-free bridging. However, ARC does not exist in "Swift-space", and the type system has changed.
How do I turn my streams into instances of
CMutablePointer<Unmanaged<CFReadStream>?>, and CMutablePointer<Unmanaged<CFWriteStream>?>
And then convert them back into NSStream
subclasses after the CFStreamCreatePairWithSocketToHost
call?
I got it to work, here's my code: Make sure you keep a reference of the connection class somewhere :-)
class Connection : NSObject, NSStreamDelegate { let serverAddress: CFString = "127.0.0.1" let serverPort: UInt32 = 8443 private var inputStream: NSInputStream! private var outputStream: NSOutputStream! func connect() { println("connecting...") var readStream: Unmanaged<CFReadStream>? var writeStream: Unmanaged<CFWriteStream>? CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream) // Documentation suggests readStream and writeStream can be assumed to // be non-nil. If you believe otherwise, you can test if either is nil // and implement whatever error-handling you wish. self.inputStream = readStream!.takeRetainedValue() self.outputStream = writeStream!.takeRetainedValue() self.inputStream.delegate = self self.outputStream.delegate = self self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) self.inputStream.open() self.outputStream.open() } func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) { println("stream event") } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With