6

CoreBlueToothフレームワークを使用して、Peripheralの書き込み可能な特性の1つに書き込みます。私は "didWriteValueForCharacteristic:error:"デリゲートを中央に実装しています。これは常にエラーの下で私を返しています。私の周辺機器でデータを受け取っていますが。CoreBlueTooth:データが書き込み可能な特性に書き込まれてもエラーが発生する

Error Domain=CBErrorDomain Code=0 "Unknown error." UserInfo=0x166762e0 {NSLocalizedDescription=Unknown error.} 

私のコードで私のself.dataは3つのキーと値を持つNSDictionaryです。

// Central 

- (void)centralManagerDidUpdateState:(CBCentralManager *)iCentral { 
    if (iCentral.state != CBCentralManagerStatePoweredOn) { 
     return; 
    } 

    [self.centralManager scanForPeripheralsWithServices:self.peripheralServices options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES}]; 
} 


- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)iPeripheral advertisementData:(NSDictionary *)iAdvertisementData RSSI:(NSNumber *)iRSSI { 
    if (self.discoveredPeripheral != iPeripheral) { 
     // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it 
     self.discoveredPeripheral = iPeripheral; 

     // Connect to the discovered peripheral 
     [self.centralManager connectPeripheral:iPeripheral options:nil]; 
    } 
} 

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)iPeripheral advertisementData:(NSDictionary *)iAdvertisementData RSSI:(NSNumber *)iRSSI { 
    if (self.discoveredPeripheral != iPeripheral) { 
     // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it 
     self.discoveredPeripheral = iPeripheral; 

     // Connect to the discovered peripheral 
     [self.centralManager connectPeripheral:iPeripheral options:nil]; 
    } 
} 


// We've connected to the peripheral, now we need to discover the services and characteristics to find the 'writeable' characteristic. 
- (void)centralManager:(CBCentralManager *)iCentral didConnectPeripheral:(CBPeripheral *)iPeripheral { 
    // Stop scanning 
    [self.centralManager stopScan]; 

    // Make sure we get the discovery callbacks 
    iPeripheral.delegate = self; 

    // Search only for services that match our UUID 
    [iPeripheral discoverServices:self.peripheralServices]; 
} 


- (void)peripheral:(CBPeripheral *)iPeripheral didDiscoverServices:(NSError *)iError { 
    if (iError) { 
     [self cleanup]; 
     return; 
    } 

    // Loop through the newly filled peripheral.services array, just in case there's more than one. 
    for (CBService *service in iPeripheral.services) { 
     [iPeripheral discoverCharacteristics:@[self.writeableCharactersticsUUID] forService:service]; 
    } 
} 


// Write the data into peripheral's characterstics 
- (void)peripheral:(CBPeripheral *)iPeripheral didDiscoverCharacteristicsForService:(CBService *)iService error:(NSError *)iError { 
    if (iError) { 
     [self cleanup]; 

     return; 
    } 

    // Find out the writable characterstics 
    for (CBCharacteristic *characteristic in iService.characteristics) { 
     if ([characteristic.UUID isEqual:self.writeableCharactersticsUUID]) { 
      NSData *dataToWrite = [NSJSONSerialization dataWithJSONObject:self.data options:0 error:nil]; 
      NSInteger dataSize = [[NSByteCountFormatter stringFromByteCount:dataToWrite.length countStyle:NSByteCountFormatterCountStyleFile] integerValue]; 
      if (dataSize > 130) { 
       NSLog(@"Cannot send more than 130 bytes"); 
       return; 
      } 

      [self.discoveredPeripheral writeValue:dataToWrite forCharacteristic:self.centralWriteableCharacteristic type:CBCharacteristicWriteWithResponse]; 

      break; 
     } 
    } 
} 


- (void)peripheral:(CBPeripheral *)iPeripheral didWriteValueForCharacteristic:(CBCharacteristic *)iCharacteristic error:(NSError *)iError { 
    NSLog(@"Error = %@", iError); 
} 


- (void)cleanup { 
    // Don't do anything if we're not connected 
    if (self.discoveredPeripheral.state != CBPeripheralStateConnected) { 
     return; 
    } 

    // If we've got this far, we're connected, but we're not subscribed, so we just disconnect 
    [self.centralManager cancelPeripheralConnection:self.discoveredPeripheral]; 
} 


// Peripheral 

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)iPeripheral { 
    if (iPeripheral.state != CBPeripheralManagerStatePoweredOn) { 
     return; 
    } 

    CBMutableCharacteristic *characteristic = [[CBMutableCharacteristic alloc] initWithType:iCID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable]; 

    CBMutableService *writableService = [[CBMutableService alloc] initWithType:iServiceId primary:YES]; 
    writableService.characteristics = @[characteristic]; 

    //[self.peripheralManager removeAllServices]; 
    [self.peripheralManager addService:writableService]; 
    [self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[iServiceId]}]; 
} 

- (void)peripheralManager:(CBPeripheralManager *)iPeripheral didReceiveWriteRequests:(NSArray *)iRequests { 
    CBATTRequest *aRequest = iRequests[0]; 
    NSData *aData = aRequest.value; 
    NSDictionary *aResponse = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:aData options:NSJSONReadingMutableContainers error:nil]; 

    NSLog(@"Received Data = %@", aResponse); 
} 

答えて

9

私はそれを理解しました。問題は「特性」タイプの問題でした。 "CBCharacteristicWriteWithResponse"の代わりに "CBCharacteristicWriteWithoutResponse"を使用していました。

私はこれを読んだ後、これをした:

writeValue forCharacteristic writeType、この機能は、デバイス上の特性に書き込むための主要な機能です。 writeTypeプロパティは、応答なしで書き込みするか、応答で書き込むかのいずれかに設定されます。応答を伴う書き込みを使用すると、iOSデバイスがok応答とコールバックの受信を待機している間に、ペリフェラルへのすべての書き込みがキャッシュされます。書き込み無応答が使用されると、データはキャッシュされません。 RCカーやヘリコプターのようにレスポンスで書込みを使用するときに、待ち時間の短いものを使用する場合は重要ですが、iOSデバイスが遅れて応答することはありません...各書き込みでdidWriteCharacteristicコールバックが呼び出されます。

+0

私は(変更ファームウェアの要件に)再びこの正確に同じ問題の時間と時間を持っていました。私は毎回それをGoogleにする必要があります:) – SJoshi

+0

私は同じ変更を加えたが、それでも私は周辺機器の端に任意の呼び出しを取得していない。私はPeripheralManagerの 'didReceiveWriteRequests'メソッドで何か更新を探しています。私は正しいですか? – Mrug

2

これを他の人に任せても、OPの回答は正しくありません。

ここで行われたミスは、彼がこの機能では、彼の特性を更新しなかったことである:なし特性が更新されることがわかっていないので

- (void)peripheralManager:(CBPeripheralManager *)iPeripheral didReceiveWriteRequests:(NSArray *)iRequests { 
    CBATTRequest *aRequest = iRequests[0]; 
    NSData *aData = aRequest.value; 
    NSDictionary *aResponse = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:aData options:NSJSONReadingMutableContainers error:nil]; 


    NSLog(@"Received Data = %@", aResponse); 
} 

、OSは何かが間違っていたとエラーが発生を前提としています。

CBMutableCharacteristic *characteristic = [[CBMutableCharacteristic alloc] initWithType:iCID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable]; 

このコードは実際に応答して特徴的な書き込み可能を持つように設定され、何の応答を指定しない列挙型は次のとおりです。

CBCharacteristicPropertyWriteWithoutResponse 

希望これは、この上でつまずく人を支援します。

4

後世のためにこれを記録する:あなたは、エラーを防ぐために応答する必要があります:

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests 
{ 
    // respond! 
    [peripheral respondToRequest:[requests objectAtIndex:0] withResult:CBATTErrorSuccess]; 
+0

動作しません。まだgetitngデータNull –

+0

うまく動作します。ありがとう! – flame3

関連する問題