Search code examples
objective-cswiftcocoanetwork-programmingnsstream

Setting TCP_NODELAY for NSOutputStream in Swift


This answer and this answer both show how to set TCP_NODELAY for NSOutputStream in Objective-C. I need some help on getting this to work in Swift, and I believe that it's probably just a mistake I'm making with the API.

This is the Objective-C solution that supposedly works:

CFDataRef nativeSocket = CFWriteStreamCopyProperty(`myWriteStream`, kCFStreamPropertySocketNativeHandle);
CFSocketNativeHandle *sock = (CFSocketNativeHandle *)CFDataGetBytePtr(nativeSocket);
setsockopt(*sock, IPPROTO_TCP, TCP_NODELAY, &(int){ 1 }, sizeof(int));
CFRelease(nativeSocket);

This is my attempt at translating it into Swift:

let nativeSocket: CFDataRef = CFWriteStreamCopyProperty(myWriteStream, kCFStreamPropertySocketNativeHandle).data
let sock = CFSocketNativeHandle(CFDataGetBytePtr(nativeSocket).memory)
var one = Int(1)
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, UInt32(sizeofValue(one)))

The real issue is getting a CFDataRef from myWriteStream (an NSOutputStream), and then getting a CFSocketNativeHandle from that. In the Swift code above, it always crashes on the first line while trying to create nativeSocket (specifically, trying to access the data property).

Can somebody help me out with this?


Solution

  • Ok, so after a while I figured it out. Here's the working code in case somebody else needs it:

    let socketData = CFWriteStreamCopyProperty(self.outputStream!, kCFStreamPropertySocketNativeHandle) as! CFData
    let handle = CFSocketNativeHandle(CFDataGetBytePtr(socketData).memory)
    var one: Int = 1
    let size = UInt32(sizeofValue(one))
    setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &one, size)