web-dev-qa-db-ja.com

iOS6デバイスをBLEペリフェラルとして実行する

ご存知のように、iOS 6はBLE周辺機器として実行中のデバイス(iPhone 4s以降および新しいiPad)をサポートしています。 WWDC 2012セッション705には、「高度なコアBluetooth」と呼ばれるデモがあります。 Appleにソースコードを頼んだ。彼らは私にソースコードの修正版(BTLE_Transfer_Draft)を送ってくれました。その後私は:

  • IPhone 5(iOS 6)の「周辺機器モード」でアプリを実行し、「広告」を開始します
  • 「セントラルモード」で新しいiPad(iOS 5.1.1)でアプリを実行します

問題は、周辺機器がまったく発見されないことです。そのため、AppStoreからダウンロードしたものを含む他のテストアプリケーションを使用しています。すべてが周辺機器の検出に失敗しました。問題はBTLE_Transfer_Draftにあるはずだと思います。ソースコード全体を提示できるかどうかわからないからです。したがって、ここでは「周辺モード」の部分を示します。

- (void)viewDidLoad {
    [super viewDidLoad];

    // Start up the CBPeripheralManager
    _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
}

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
    // Opt out from any other state
    if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
        return;
    }

    // We're in CBPeripheralManagerStatePoweredOn state...
    NSLog(@"self.peripheralManager powered on.");

    // ... so build our service.

    // Start with the CBMutableCharacteristic
    self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]
                                                                  properties:CBCharacteristicPropertyNotify
                                                                       value:nil
                                                                 permissions:CBAttributePermissionsReadable];

    // Then the service
    CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]
                                                                    primary:YES];

    // Add the characteristic to the service
    transferService.characteristics = @[self.transferCharacteristic];

    // And add it to the peripheral manager
    [self.peripheralManager addService:transferService];
}

/** Start advertising
 */
- (IBAction)switchChanged:(id)sender
{
    if (self.advertisingSwitch.on) {
        // All we advertise is our service's UUID
        [self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
    }
    else {
        [self.peripheralManager stopAdvertising];
    }
}

BLEはパワーオン状態であり、startAdvertisingが呼び出されます。しかし、BLEセントラルはそれを発見することはできません。

投稿の更新:

mttrb の提案によると、Advertisingを開始するときに「CBAdvertisementDataLocalNameKey」を追加しました。しかし、私のサービスは、アプリストアの一部のアプリを含むほとんどのアプリでまだ検出できません。私のサービスを検出できるアプリは、「BLEスキャナー」と呼ばれるアプリストアのアプリだけです。

私の質問は:これは私のアプリケーションが周辺機器として機能していることを意味しますか?しかし、なぜ私自身のコードがサービスを発見できないのですか?どのようにデバッグするのですか?

セントラルモードでの私のコードは次のようになります。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Start up the CBCentralManager
    _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    if (central.state != CBCentralManagerStatePoweredOn) {
        return;
    }
    [self.centralManager scanForPeripheralsWithServices:nil options:nil];
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
......
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    if (error) {
        NSLog(@"Error discovering services: %@", [error localizedDescription]);
        return;
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    // Deal with errors (if any)
    if (error) {
        NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
        return;
    }
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"Peripheral Disconnected");
    self.discoveredPeripheral = nil;
}

DidDiscoverPeripheralとdidDiscoverServicesが呼び出されることはありません。何が悪いのでしょうか?何か案が?ありがとう

16
Bagusflyer

LightBlue という高品質の無料アプリもあり、コードのテストに使用できます。周辺機器モードでアドバタイズするすべてのデバイスをピックアップできる必要があります。デバイスが正しく機能していることを確認したい場合は、それ自体をアドバタイジングペリフェラルに変えることもできます。

12
kevinejohn

このGitハブプロジェクトは、CBPeripheralManagerAPIにも光を当てています。呼び出されます PeripheralModeTest 。この行は、広告データの設定に特に役立ちます

 NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey : @"Device Name", CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:CBUUIDGenericAccessProfileString]]};

Apple iOS Developer Libraryにはまだ公式ドキュメントはありませんが、具体的には、広告の繰り返し期間の設定については何でも。

3
Nick T

startAdvertising:メソッド呼び出しをperipheralManagerDidUpdateState:デリゲートメソッドの最後に移動して、それが役立つかどうかを確認します。

また、CBAdvertisementDataLocalNameKeyキーと値のペアをstartAdvertising:メソッド呼び出しに追加します。広告に名前がない場合、物事は信頼できないことがわかりました。

最後に、App Storeで入手できる BLExplr app に投資して、周辺機器のスキャンを支援します。それはあなたのセントラルが正しく働いているという仮定を取り除きます。

3
mttrb

BTLE Transfer の例には、この(奇数)コードが含まれているため、問題が発生する可能性があります。

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    // Reject any where the value is above reasonable range
    if (RSSI.integerValue > -15) {
        return;
    }

    // Reject if the signal strength is too low to be close enough (Close is around -22dB)
    if (RSSI.integerValue < -35) {
        return;
    }

意味がないので、これら2つのifステートメントを削除してください。

ペリフェラルからセントラルに送信される大量のメッセージをテストするために使用できる簡略化されたバージョンを利用可能にしました ここ

CBPeripheralManagerクラスはiOS6.0で最初に導入されたことに注意してください。

2
Jens Schwarzer

BTLE Central Peripheral Transfer の魔女バージョンはわかりませんが、実際にテストしましたが、現在のバージョンにはiOS6が必要です。

したがって、iOS 5.1に対してリンケージをテストして、それが示す互換性の問題を確認することをお勧めします。

0
vedrano