Swift: Bonjour, NSNetService & IP Addresses

Good morning. At least it’s a good morning here. I have recently been exploring Bonjour in Swift – I have never investigated Bonjour as a concept as networking is one of the weaker areas of my coding ability. However recently I’ve needed to look into it for work reasons.

I had been able to scan the network for a certain protocol and find devices on the network. I’d get their name but needed to resolve their IP Addresses which are not immediately available upon discovery.

I’d been using some Objective-C code and a bridging header to resolve the addresses. So here is what I was using.

-(NSString* )IPAddressesFromData:(NSNetService *)service {
    for (NSData *address in [service addresses]) {
        struct sockaddr_in *socketAddress = (struct sockaddr_in *) [address bytes];
        //NSLog(@"Service name: %@ , ip: %s , port %i", [service name], inet_ntoa(socketAddress->sin_addr), [service port]);
        NSString *retString = [NSString stringWithFormat:@"%s", inet_ntoa(socketAddress->sin_addr)];
        return retString;
    return @"Unknown";

Now, while this works, it’s a clutter as I wanted to keep all the code in my Swift project… Swift. Surely there had to be a way. After a quick post to StackOverflow, I was redirected to a post with some relevant code. And now I have this (directly in a┬áNSNetServiceDelegate method).

func netServiceDidResolveAddress(sender: NSNetService){
    let theAddress = sender.addresses!.first! as NSData
    var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
    if getnameinfo(UnsafePointer(theAddress.bytes), socklen_t(theAddress.length), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
        if let numAddress = String.fromCString(hostname){
            print("CONVERT IP: \(numAddress)")

Would you look at that? A pure Swift solution. I’ve since removed my Obj-C class and bridging header and now everything is so much cleaner. And seriously – faster.