swiftbonjournsnetservicensnetservicebrowser

Using NSNetService and NSNetServiceBrowser on a Swift application


I'd like to make an app that is able to discover and connect to peers on the local network, so i've decided to implement it in swift, using the bonjour framework.

However, i can't make Bonjour work using Swift, and I can't figure out why. Here is the code I use to test this service :

import Foundation

let BM_DOMAIN = "local"
let BM_TYPE = "_helloworld._tcp."
let BM_NAME = "hello"
let BM_PORT : CInt = 6543

/// Netservice
let nsns = NSNetService(domain: BM_DOMAIN, 
        type: BM_TYPE, name: BM_NAME, port: BM_PORT)
let nsnsdel = BMNSDelegate() //see bellow
nsns.delegate = nsnsdel
nsns.publish()

/// Net service browser.
let nsb = NSNetServiceBrowser()
let nsbdel = BMBrowserDelegate() //see bellow
nsb.delegate = nsbdel
nsb.searchForServicesOfType(BM_TYPE, inDomain: BM_DOMAIN)

println("press enter")
// this prevents the app from quitting instantly.
NSFileHandle.fileHandleWithStandardInput().availableData 

The delegates are glue code that simply prints every call to the console.

class BMNSDelegate : NSObject, NSNetServiceDelegate {
    func netServiceWillPublish(sender: NSNetService!) {
        println("netServiceWillPublish:sender");
    }
    // .....and so on for the 8 other methods.....
}

class BMBrowserDelegate : NSObject, NSNetServiceBrowserDelegate {
    func netServiceBrowserWillSearch(aNetServiceBrowser: NSNetServiceBrowser!){
        println("netServiceBrowserWillSearch")
    }
    // .....and so on for the 6 other methods.....
}

Here is the output of this sample code :

netServiceWillPublish:sender
netServiceBrowserWillSearch
press enter

If I use Bonjour browser, I can see that the service is correctly published. However the callbacks in both delegates are not called, beside the **WillPublish ones :-(

After intense debugging (and reading on stackoverflow), I can't figure why it does not work. Any ideas ?

(I'm using Mac OS X 10.9.3, and xcode 6.0 beta build 6A215l)


Solution

  • NSNetServiceBrowser needs a runloop to execute. Instead of reading from stdin, call NSRunLoop.currentRunLoop().run().