Toll-free bridging and pointer access in Swift
core-foundation, objective-c, swift, toll-free-bridging
Solution
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")
}
}
Problem
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?