質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.37%

  • iOS

    4398questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • Bluetooth

    257questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • IoT

    63questions

    IoT(Internet of Things)とは、インターネットがコンピュータなどの情報・通信機器のネットワークだけでなく、世の中のある様々なモノに接続されて自動認識・自動制御・遠隔計測などの能力を備えることです。「モノのインターネット」と一般的にいわれます。

iOS、BLE接続でCBCentralManagerOptionRestoreIdentifierKeyを設定するとBLEと接続ができなくなる。

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 2,615

SatoTakeshiX

score 106

iOSでBLE接続をするアプリを作っております。
iOSアプリがBLE通信の受信側(セントラル)です。
アプリが停止したあとも自動でBLE機器の近くに来た時に通信させたいと思い、状態の保存と復元を実装しようとしました。
ところが、CBCentralManagerクラスの初期化のオプションCBCentralManagerOptionRestoreIdentifierKeyを追加したところ、アプリ側BLEの受信ができなくなってしまいました。

何か、接続方法で間違ってしまったのでしょうか。接続できるようにしたいと思っています。なにか情報があれば(確認すべき点)お伝えいただけると幸いです。

また不足している情報があればお伝え下さい。

-(void)initPropertyWithUUIDs:(NSArray *)UUIDS
{
    //BluetoothがOFFの場合にアラートを出す
    NSDictionary *options = @{

                              CBCentralManagerOptionRestoreIdentifierKey:@"myidentifierKey",//->追加して接続ができなくなってしまいました。
                              CBCentralManagerOptionShowPowerAlertKey:@YES

                              };

    self.centralManager = [[CBCentralManager alloc] initWithDelegate:self
                                                               queue:nil
                                                             options:options];
}

上記の初期化をしたところ、BLEの接続ができなくなってしまいました。
ちなみに下記のようにコメントアウトして、CBCentralManagerOptionShowPowerAlertKeyのみ指定したところ接続を確認しています。
CBCentralManagerOptionRestoreIdentifierKeyの追加だけでなぜ接続すらできなくなってしまったのかがわからい状態です。

//BluetoothがOFFの場合にアラートを出す
    NSDictionary *options = @{

                             // CBCentralManagerOptionRestoreIdentifierKey:@"myidentifierKey",//->追加して接続ができなくなってしまいました。
                              CBCentralManagerOptionShowPowerAlertKey:@YES

                              };

ちなみに、実際に接続させるメソッドはこちらです。

-(void)connectStart
{
    // 探索対象のデバイスが持つサービスを指定
    NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kUUIDforService],nil];
    // 単一デバイスの発見イベントを重複して発行させない
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
                                                        forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
    //接続開始
    [self.centralManager scanForPeripheralsWithServices:services
                                                options:options];
}

また、状態の保存と復元を行うデリゲートメソッドも下記のように実装しています。

-(void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)dict
{

    NSLog(@"状態の保存と復元");

    NSString *msg = [NSString stringWithFormat:@"セントラル復元:%@", dict];

    //復元されたかどうかをみるためにローカル通知を発行させる
    if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {

        UILocalNotification *localNotification = [UILocalNotification new];
        localNotification.alertBody = msg;
        localNotification.fireDate = [NSDate date];
        localNotification.soundName = UILocalNotificationDefaultSoundName;
        [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

    }
}

iPhone6 plus iOS9.2で開発しています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

queueの指定をするとどうなるでしょうか?

dispatch_queue_t queue = dispatch_queue_create("hogehoge", 0);
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self
                                                           queue:queue
                                                         options:options];

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/01/21 18:56

    @fuzzballさんありがとうございます。
    お伝え頂いたとおり、queueを設定しました。しかし、まだBLEに接続されません。。

    スレッドを変えたほうがいいのでしょうか。

    `self.centralManager`などのBLEと通信する処理と`CBCentralManagerDelegate`デリゲートメソッドの実装はシングルトンで一つのクラスにまとめてつくっていますが、それが悪さをしていますかね??

    ```Objective C
    self.centralManager = [[CBCentralManager alloc] initWithDelegate:self
    queue:queue
    options:options];

    ```

    キャンセル

  • 2016/01/21 19:45

    CentralManagerのstateはPoweredOnになっていますか?

    キャンセル

  • 2016/01/21 20:03

    >CentralManagerのstateはPoweredOnになっていますか?
    実際接続を実行する下記のメソッドでself.centralManagerのステイタスを調べました。

    ```Objective-C
    -(void)connectStart
    {
    // 探索対象のデバイスが持つサービスを指定
    NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kUUIDforService],nil];
    // 単一デバイスの発見イベントを重複して発行させない
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
    forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
    //接続開始
    [self.centralManager scanForPeripheralsWithServices:services
    options:options];


    switch (self.centralManager.state) {
    case CBCentralManagerStatePoweredOff:
    NSLog(@"CBCentralManagerStatePoweredOff");
    break;
    case CBCentralManagerStatePoweredOn:
    NSLog(@"CBCentralManagerStatePoweredOn");
    break;
    case CBCentralManagerStateResetting:
    NSLog(@"CBCentralManagerStateResetting");
    break;
    case CBCentralManagerStateUnauthorized:
    NSLog(@"CBCentralManagerStateUnauthorized");
    break;
    case CBCentralManagerStateUnknown:
    NSLog(@"CBCentralManagerStateUnknown");
    break;
    case CBCentralManagerStateUnsupported:
    NSLog(@"CBCentralManagerStateUnsupported");
    break;
    default:
    break;
    }


    }
    ```

    するとNSLogの結果は以下のようになっていました。

    ```
    2016-01-21 20:00:07.732 BLEAPP[592:219895] CBCentralManagerStateUnsupported
    ```

    CBCentralManagerStateUnsupportedってどうゆう状態でしょうか?
    返信ありがとうございます!

    キャンセル

  • 2016/01/21 20:05

    あ、ちょっと私も調べます。。

    キャンセル

  • 2016/01/21 20:12

    https://developer.apple.com/library/mac/documentation/CoreBluetooth/Reference/CBCentralManager_Class/#//apple_ref/c/tdef/CBCentralManagerState
    をみました。

    >CBCentralManagerStateUnsupported
    >The platform does not support Bluetooth low energy.

    BLEが使えないよってことですかね。。なぜオプション追加しただけでサポート切れるのでしょう。。

    キャンセル

  • 2016/01/21 20:22

    .BLE通信はバックグラウンドでも通信を許可しています

    キャンセル

  • 2016/01/21 20:33

    スマホからなので手抜きコメントです。

    Unsupportedについてですが、init直後はPoweredOnになっていません。
    http://qiita.com/shu223/items/f67f1b0fb1840cf0bd63
    この記事のトラブル1を参照して下さい。

    これに該当していないでしょうか?

    キャンセル

  • 2016/01/22 01:41

    ありがとうございます。明日確認します!

    キャンセル

  • 2016/01/22 15:21

    centralManagerDidUpdateStateメソッドで、下記のように、ステータスを確認しつつ、スキャンしようとしたところ、始めに、CBCentralManagerStatePoweredOnの状態になったあとに、CBCentralManagerStateUnsupportedに変化してしまっておりました。
    ```
    #pragma mark - CBCentralManagerDelegate
    -(void)centralManagerDidUpdateState:(CBCentralManager *)central
    {

    //PowerdONになったらスキャンOK
    //初期化してそのままスキャンしたいときは、したの処理でスキャンメソッドを呼ぶ
    switch (central.state) {
    case CBCentralManagerStatePoweredOn:
    NSLog(@"CBCentralManagerStatePoweredOn:%s", __func__);
    self.sensorStatus = SENSOR_STATUS_POWERED_ON;

    //cause table of found peripherals to be updated
    if ([self.delegate respondsToSelector:@selector(statusChanged:)])
    {
    [self.delegate statusChanged:SENSOR_STATUS_POWERED_ON];
    }

    break;

    case CBCentralManagerStateUnsupported:

    NSLog(@"CBCentralManagerStateUnsupported:%s", __func__);

    break;

    case CBCentralManagerStateUnknown:
    NSLog(@"CBCentralManagerStateUnknown:%s", __func__);
    break;

    case CBCentralManagerStateUnauthorized:
    NSLog(@"CBCentralManagerStateUnauthorized:%s", __func__);
    break;
    case CBCentralManagerStateResetting:
    NSLog(@"CBCentralManagerStateResetting:%s", __func__);
    break;

    case CBCentralManagerStatePoweredOff:
    NSLog(@"CBCentralManagerStatePoweredOff:%s", __func__);
    break;

    default:
    break;
    }

    }
    ```

    実行時のログです。
    ```
    2016-01-22 15:17:35.051 BLEAPP[2888:727006] CBCentralManagerStatePoweredOn:-[Sensor centralManagerDidUpdateState:]
    2016-01-22 15:17:35.051 BLEAPP[2888:727006] CBCentralManagerStateUnsupported:-[Sensor centralManagerDidUpdateState:]
    ```

    キャンセル

  • 2016/01/22 15:55

    現状のプロジェクトがCentralManagerの初期化がおかしい可能性があるので、新しくプロジェクト作って試してみます。

    キャンセル

  • 2016/01/22 17:27

    fuzzballさん
    新しいプロジェクトを作って、CBCentralManagerOptionRestoreIdentifierKeyを設定してBLE通信ができました。
    また、プロセス切って、復元メソッドが呼ばれるところまで確認ができました!
    何度も返信いただき感謝致します。
    おそらく、現状のプロジェクトがCentralManagerのインスタンスを数回初期化してしまって、ステータスがおかしくなってしまっていたのかと思います。

    自分ひとりではここまでたどり着けませんでした。
    ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • iOS

    4398questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • Bluetooth

    257questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • IoT

    63questions

    IoT(Internet of Things)とは、インターネットがコンピュータなどの情報・通信機器のネットワークだけでなく、世の中のある様々なモノに接続されて自動認識・自動制御・遠隔計測などの能力を備えることです。「モノのインターネット」と一般的にいわれます。