My function below creates a CFSocket
and tries to create input and output streams with the original function's owner as the delegate.
@objc
public class BonjourPublisher: NSObject, NSNetServiceDelegate, NSStreamDelegate {
private func hookUpSocket(fd: CFSocketNativeHandle) throws {
var context = CFSocketContext()
var selfPtr = self
withUnsafeMutablePointer(&selfPtr) {
context.info = UnsafeMutablePointer<Void>($0)
}
serviceSocket = withUnsafePointer(&context) {
CFSocketCreateWithNative(nil, fd, CFSocketCallBackType.AcceptCallBack.rawValue, CallbackListen, UnsafePointer<CFSocketContext>($0))
}
guard serviceSocket != nil && CFSocketIsValid(serviceSocket) else {
throw BonjourServerError.CreatingNativeSocket
}
serviceRunLoopSource = CFSocketCreateRunLoopSource(nil, serviceSocket, 0)
guard serviceRunLoopSource != nil && CFRunLoopSourceIsValid(serviceRunLoopSource) else {
throw BonjourServerError.CreatingSocketRunLoopSource
}
CFRunLoopAddSource(CFRunLoopGetCurrent(), serviceRunLoopSource, kCFRunLoopCommonModes)
}
}
func CallbackListen(s: CFSocket!, callbackType: CFSocketCallBackType, address: CFData!, data: UnsafePointer<Void>, info: UnsafeMutablePointer<Void>) {
let fd = UnsafePointer<CFSocketNativeHandle>(data)
var readStream: Unmanaged<CFReadStreamRef>?
var writeStream: Unmanaged<CFWriteStreamRef>?
CFStreamCreatePairWithSocket(nil, fd.memory, &readStream, &writeStream)
let inputStream: NSInputStream = readStream!.takeRetainedValue()
let outputStream: NSOutputStream = writeStream!.takeRetainedValue()
inputStream.setProperty(kCFBooleanTrue, forKey: kCFStreamPropertyShouldCloseNativeSocket as String)
let publisherPtr = UnsafeMutablePointer<BonjourPublisher>(info)
let publisher: BonjourPublisher = publisherPtr.memory
inputStream.delegate = publisher
outputStream.delegate = publisher
inputStream.open()
outputStream.open()
}
But the first line to refer to publisherPtr.memory
gets an EXC_BAD_ACCESS
exception. What's the problem here? Is it an ARC issue, or am I messing up my pointer passing?