iPhone/iPod TouchのBonjour/NSNetServiceBrowserは、少なくとも、サポートされているデバイスで、サービスの検出にWifiとBluetoothの両方を利用します。サービスの閲覧を開始するたびに、WiFiとBluetoothの両方が検索されます(これは、iPhoneのConsoleでオーガナイザで確認できます)。あなたのシミュレータ「デバイス」はBluetoothを使用できないため、あなたのiPhoneはWiFi経由でそれを検出します。しかし、あなたのiPhoneに公開するためにNSNetServiceを使用している場合は、WiFi と Bluetooth(サポートされている場合)の両方で公開しています。 BT対応のハードウェア上で動作するNSNetServiceBrowserは、両方のインスタンスを忠実に見つけ出し、デリゲートコールバックを介して両方を報告します。
Bluetooth PANの設定にはWi-Fi経由で公開するよりも時間がかかります。そのため、Wi-Fiベースのサービスがすべて検出されて解決された後にBT発見サービスがよく表示されます。 2つの実際のデバイスをテストするとき、私は両方のサービスが私のUIに現れているのを見たことがあります(通常、他の電話がクラッシュした後にのみです)。
しかし、何らかの不満足なコーディングがあります。最善の方法は、netService:didNotResolve:を使用して(i)解決を再試行するか、(ii)netServiceインスタンスを無効にして、他の電話がアプリを再起動するのを待つことです。
また、状況が間違っている可能性のあるいくつかの領域があります。あなたに提供されたNSNetServiceインスタンスはオートレリースされているので、それを保持する必要があります。ほとんどの人はそれをNSMutableArrayまたはNSMutableDictionaryに追加します。その場合は、オブジェクトを追加する前に正しく初期化してください。 nilへのメッセージは完全にOKなので、addObject:をnilに送ると、すべてが正常に動作しているように見えます。それ以外はそうではありません。これはBonjourのトラブルシューティングで非常に頻繁に起こります。 NSNetServiceが実行中のrunloopにスケジュールされていること、およびデフォルトまたは共通モードで実行されていることを確認してください。
アップルに提出されているオープンバグがあります(10/4/09現在)ので、Bonjourによるアップデートではデリゲートメソッドが起動することはありません。私はこれが3GS上でしか起こらないことを観察しました。結果は、ネットワークと同期していないクライアントアプリケーションです。
NSNetServiceBrowserは、(公称条件の下で)サービスがネットワークを離れるときに一貫して通知する必要があります。上記のバグは断続的なものであり、明らかにハードウェア固有のものです。それが一貫して発生している場合は、アプリが例外をスローしている可能性があります。バックグラウンドスレッドを使用している場合は、アプリ全体がクラッシュすることなく発生する可能性があります。 iPhoneのコンソールを確認し、エラーメッセージを記録したい場合があります。シンボルobjc_exception_throwにブレークポイントを設定していることを確認してください。
私は貴重であると分かった別のトラブルシューティングのヒントを紹介します。 dns-sd -B _serviceNameコマンドを使用して、端末経由でBonjourブロードキャストをあなたのdevマシンで監視してください。これにより、あなたのサービスのためにローカルネットワーク上のすべての出入りを見ることができます。あなたのアプリケーションが終了しても、dns-sdにRemoveイベントが表示されない場合は、コードを再訪する必要があります。 dns-sdがremoveイベントを表示しても、他のアプリが正しく処理しない場合は、上記のバグが表示されている可能性があります。あなたのコードがあなたが思っていることをしていない場合もあります。これは、Wifi-to-WifiサービスのBonjourのトラブルシューティングに役立ちます。 Bluetooth to Bluetoothは、iPhone Simulatorからサポートされていません。
私の開発ブログでTroubleshooting Bonjour Networking for the iPhoneの記事全文を読む。
また、iPhone OS 3.xがdns-sdキャッシュをネットワークと同期させておくのに問題があるようだと付け加えます。その結果、サービス削除イベントが「ミス」することがあり、古いエントリが生成されることがあります。私は通常、この問題を解決するために、WiFiをオフにしてから、私のアプリケーションを再起動して再起動します。 – Zack