[解決]didDiscoverServices が呼ばれない [corebluetooth] [iOS 8.2 & 8.3]
📅 March 20, 2015
•⏱️5 min read
[解決しました! 15/9/4]
iOS8.4リリース直後くらいに本件解決してたのですが、記事にしていませんでした。2ヶ月遅れ…。 結論を述べますとiOSの通信相手であるハード側のバグでした。つまりiOSは無罪でした。 どうもiOS8.1か8.2あたりでBLEの通信仕様が変わったらしく、 通信相手である端末が新しい仕様に対応していなかったことが原因でした。
私の場合、相手端末のソースコードはサンプルプログラムを使わせていただいてたんですけど、 そのサンプルプログラムが新しい仕様に対応していませんでした。 新しいサンプルプログラムが広報されていたので試したところ、 本件は見事に解決となりました。
いやー解決して良かったですけど、正直長かったです。けっこう悩みました。 ちなみに私が使用していた相手端末は、ランニングエレクトロニクスさんの小型マイコン基板 SBDBT です。 もし、同じものをお使いで同じ悩みを抱えている方は、プログラムが最新かご確認を!
[追記 15/4/10]
iOS8.3がリリースされましたのでアップデートして試したところ、iOS8.3でも同現象が確認されました。 8.3のアップデートでかなりのバグが修正されたようなので、こちらも修正されているかと思ったのですが残念。 直っていないということは、もしかしてバグではなくて私の書き方が悪いのかもしれませんね。
DisconnectするとBLEアプリが落ちるようになった
BLEを一度でも切断するとその後、BLEを再接続しても データの読み書きをしようとすると落ちるようになりました。 つまり最初の一回目の接続は、普通にデータ通信できるんですけど、 一度でも切断するとその後データの読み書きができなくなります。
応急処置としては、iOSの再起動です。 これでとりあえず最初の一回目は正常に動作するようになります。
ちなみに落ちたときのログは以下みたいな感じ
2015-03-20 XX:XX:XX.XXX [XXX:XXXX] *** Assertion failure in -[CBPeripheral writeValue:forCharacteristic:type:], /SourceCache/CoreBluetooth/CoreBluetooth-256/CBPeripheral.m:395 2015-03-20 XX:XX:XX.XXX [XXX:XXXX] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: characteristic != nil' libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
didDiscoverServices が呼ばれない
デバッグしてみたら一度切断するとデリゲートメソッドが 呼ばれなくなることを発見しました。iOSアプリでBLE実装となると CoreBluetooth を使うことが多いと思います。 処理手順をかなりざっくり言うと ペリフェラルを検索して接続 ↓ ペリフェラルに対してサービスを検索 ↓ サービスに対してキャラクタリスティックを検索 ↓ キャラクタリスティックに対してデータを読み書き って手順で corebluetooth は動いてるみたいなのですが、 この ペリフェラル、サービス、キャラクタリスティックのどの検索も デリゲートメソッドで呼ばれたメソッド内で処理されます。
で、一度切断するとサービスを検索してくる「didDiscoverServices」って デリゲートメソッドが呼ばれません。
これが呼ばれないってことは次のキャラクタリスティックを検索する デリゲートメソッドも呼ばれないのでデータを読み書きしようとして エラーが起きちゃいます。
というわけでこれが原因ですね。
原因は、iOS 8.2 のバグっぽい?
どうしてデリゲートメソッドが呼ばれないの? おかしーなーと悩んでて、やっとこ見つけました。iOS 8.2 [peripheral discoverServices:] not calling to diddiscoverservices
こっちも同様の内容かと思われます。 iOS 8.2 CoreBluetooth - CentralManager not calling delegate didDiscoverPeripherals
どうやら iOS8.2 のバグのようです。8.1ではやはり動いてたというご意見。 あー、そういえば自分も iOS8.2 にアップデートしてから発生してたかも。 すぐ気付かなかった。 Apple Watch でBLEのコード直して今回のバグでちゃったのかな?
はい、というわけで修正はあきらめて次のバージョンのリリースを待つことにします。
このバグけっこう影響大きいような。。。
ぐぐっても悲鳴あげてる人少ないし、もしかしてバグじゃないのかな??
ではでは。