[swift-users] Canonical way to cast C structs

Quinn "The Eskimo!" eskimo1 at apple.com
Mon Sep 12 15:25:31 CDT 2016

On 12 Sep 2016, at 20:39, Bouke Haarsma via swift-users <swift-users at swift.org> wrote:

> So the question remains on how to perform the casts using Swift?

In general it’s best to avoid special casing your network protocols.  The best option for doing that is <x-man-page://3/getaddrinfo> and <x-man-page://3/getnameinfo> calls.  Specifically, with `getnameinfo`, if you specify `NI_NUMERICHOST` it’ll give you back an string representation of the address without hitting the DNS.  Better yet, it starts with a (const sockaddr *), so you don’t need to extract the IP address from your CFData, you just need the base address of that data as the right type, and the `Data` type makes that easy.

So, assuming `addrCF` is your CFData, here’s how to get a string representation.

let addr = addrCF as NSData as Data
let saLen = socklen_t(addr.count)
let addrStr = addr.withUnsafeBytes { (sa: UnsafePointer<sockaddr>) -> String in
    var addrStrC = [CChar](repeating: 0, count: Int(NI_MAXHOST))
    let err = getnameinfo(sa, saLen, &addrStrC, saLen, nil, 0, NI_NUMERICHOST | NI_NUMERICSERV)
    guard err == 0 else { fatalError() }
    return String(utf8String: addrStrC)!

Share and Enjoy
Quinn "The Eskimo!"                    <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

More information about the swift-users mailing list