2009-08-13 5 views
3

私のモバイルアプリのデスクトップ版を作成し、無線LANでの同期をユーザーに提供します。シミュレータではすべてがうまくいきます。ネットサービス(デスクトップアプリケーションによって公開されています)を解決したり、サービスが利用できなくなったときには問題はありません。NSNetServiceBrowserがiPhone OSの未公開サービスを検索するのはなぜですか?

問題はサービスが見つかって解決された(sometiems)がサービスを利用できなくなったときにNSNetServiceBrowserが通知しないということです。これが起こると、ネットサービスブラウザはネットサービス(もはや公開されていない)がそれを解決してもそれに接続できないことを常に見つけます。いくつかの試みが失敗すると、サービスブラウザの委任者の "didRemoveService"が最後に呼び出され、アプリケーションが正しく動作するようになります。

私は自分のコードを投稿したいと思いますが、同じ問題がAppleのWiTapの例で起こっていることがわかりました。サービスは公開され、発見されますが、利用不可能になると、サービスブラウザを実行しているクライアントは更新されず、「存在すべきではない」サービスを繰り返し解決しようとします。

私はWi-FiをオフにしてWiTapを実行している(BonjourがBluetoothを使用しているため)すべてが正常に動作することを発見しました。私はWiTapが動作していないと不平を言う人がいないことが分かり、オンライン上でこの問題を見つけることはできません。何らかの理由で(おそらくiPhone OSやワイヤレスネットワークで)、ネットサービスブラウザが利用できないサービスを見つけて正しく解決できますが、接続できないのはなぜですか?

答えて

4

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の記事全文を読む。

+1

また、iPhone OS 3.xがdns-sdキャッシュをネットワークと同期させておくのに問題があるようだと付け加えます。その結果、サービス削除イベントが「ミス」することがあり、古いエントリが生成されることがあります。私は通常、この問題を解決するために、WiFiをオフにしてから、私のアプリケーションを再起動して再起動します。 – Zack

関連する問題