iPhone/iPod Touch上的Bonjour/NSNetServiceBrowser將利用Wifi和藍牙進行服務發現 - 至少在支持的設備上。每次您開始瀏覽服務時,它都會搜索WiFi和藍牙(您可以在iPhone的控制檯,管理器中進行驗證)。由於您的模擬器「設備」無法使用藍牙,因此您的iPhone通過WiFi發現它。但是,如果您使用NSNetService在iPhone上進行發佈,則您同時通過WiFi 和藍牙發佈(如果支持並啓用)。 NSNetServiceBrowser在具有BT功能的硬件上運行時,將盡職地發現兩個實例,並通過代理回調報告。
藍牙PAN設置比通過Wifi發佈需要更長的時間,所以在發現並解決所有基於Wifi的服務後,BT發現的服務通常會顯示出來。當測試兩個真實設備時,我甚至看到兩種服務都出現在我的用戶界面中(通常只有在其他手機崩潰之後)。儘管如此,它確實使一些令人沮喪的編碼。你最好的選擇是利用netService:didNotResolve:(i)重試解析,或者(ii)使netService實例無效,並等待另一個電話重新啓動他們的應用程序。
此外,還有一些其他方面可能出錯的地方。由於提供給您的NSNetService實例是自動發佈的,因此您需要保留它。大多數人將它添加到NSMutableArray或NSMutableDictionary。如果是這種情況,請確保在添加對象之前已經正確初始化了它。由於消息到零是完全正確的,如果你發送addObject:到零,它會顯示好像一切工作正常。除了它不是。這在Bonjour故障排除中經常出現,而且發生在我們身上。確保你的NSNetService被安排到一個主動運行的runloop中,並且一個運行在默認或通用模式下。
Apple提供了一個開放的bug(截至2009年10月4日),每隔一段時間,Bonjour更新都不會導致委託方法被解僱。我只觀察到這發生在3GS上。結果是客戶端應用程序與網絡不同步。
NSNetServiceBrowser應始終通知服務何時離開網絡(在名義條件下)。上面的錯誤只是一個間歇性錯誤,顯然,硬件特定。如果您發現它一直在發生,那麼您的應用很可能會拋出異常。如果您正在使用後臺線程,則可能發生這種情況,而不會導致整個應用程序崩潰。您可能需要檢查您的iPhones控制檯並記錄錯誤消息。確保你已經在符號objc_exception_throw上設置了斷點。
這是我發現的另一個故障診斷技巧,非常寶貴。使用以下命令通過終端在您的開發機器上監聽Bonjour廣播:dns-sd -B _serviceName。這樣可以讓您查看本地網絡上的所有出入事件,以便爲您提供服務。如果您的應用退出,但dns-sd不顯示Remove事件,那麼您的代碼需要重新訪問。如果dns-sd顯示刪除事件,但其他應用程序沒有正確處理它,則可能會看到上述錯誤。也可能是你的代碼沒有做你認爲正在做的事情。請記住,這隻會幫助您解決Wifi-to-Wifi服務Bonjour問題。 iPhone Simulator不支持藍牙到藍牙。
閱讀完整的文章,Troubleshooting Bonjour Networking for the iPhone,在我的開發博客。
我還會補充一點,iPhone OS 3.x似乎在保持其dns-sd緩存與網絡同步方面存在問題。因此,它有時會「錯過」服務刪除事件,從而產生陳舊的條目。我通常可以通過關閉WiFi來解決此問題,然後重新啓動並重新啓動我的應用。 – Zack 2010-01-20 15:56:19