6

Używam framework CoreBlueTooth do zapisu w jednej z zapisywalnych cech urządzeń peryferyjnych. Wdrażam "didWriteValueForCharacteristic: error:" delegate in central, który zawsze zwraca mi błąd poniżej. Chociaż otrzymałem dane na moim urządzeniu peryferyjnym.CoreBlueTooth: Uzyskiwanie błędu, nawet jeśli dane są zapisywane w zapisywalnych charakterystykach

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

W moim kodzie my self.data jest NSDictionary z 3 kluczami i wartościami.

// 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); 
} 

Odpowiedz

9

Wymyśliłem to. Problem dotyczył typu Characteristics. Zamiast "CBCharacteristicWriteWithResponse" użyłem "CBCharacteristicWriteWithoutResponse" i zadziałało.

Zrobiłem to po przeczytaniu tego:

writeValue forCharacteristic writeType, funkcja ta jest podstawową funkcją do pisania z cechą na urządzeniu. właściwość writeType jest ustawiona do zapisu bez odpowiedzi lub zapisu z odpowiedzią. Gdy używany jest zapis z odpowiedzią, wszystkie zapisy do urządzenia peryferyjnego są buforowane, gdy urządzenie z systemem iOS oczekuje na odpowiedź "ok" i wywołanie zwrotne. W przypadku braku odpowiedzi, dane nie zostaną zapisane w pamięci podręcznej. Jest to ważne, gdy używasz rzeczy, które wymagają małego opóźnienia, takich jak samochód RC lub śmigłowiec itp., Gdy używasz zapisu z odpowiedzią, urządzenie z systemem iOS może czasem pozostawać w tyle, co nie daje świetnej odpowiedzi ... Dla każdego zapisu wywoływane jest wywołanie zwrotne didWriteCharacteristic.

+0

miałem dokładnie ten sam czas emisji i godzinę (ze zmieniającymi się wymaganiami oprogramowania). Potrzebuję go za każdym razem :) – SJoshi

+0

Wprowadziłem tę samą zmianę, ale nadal nie otrzymuję żadnego połączenia z urządzeniem peryferyjnym. Szukam jakiejkolwiek aktualizacji w metodzie "didReceiveWriteRequests" w PeripheralManager. mam rację ? – Mrug

2

Pozostawienie tego tutaj dla innych osób, ale odpowiedź OP nie jest poprawna.

Błędem, który powstał tu jest, że nie aktualizuje swoją charakterystykę w tej funkcji:

- (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); 
} 

Ponieważ żadna cecha okazuje się być aktualizowane, system operacyjny zakłada coś poszło nie tak i generuje błąd.

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

Kod ten jest faktycznie ustawić mieć charakterystyczny zapisywalny z odpowiedzi, która określa enum nie odpowiedź brzmi:

CBCharacteristicPropertyWriteWithoutResponse 

Nadzieja to pomaga innym, którzy potykają się na to.

4

Nagrywanie to dla potomnych: Państwo musi reagować, aby zapobiec błąd:

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

Nie działa. wciąż getitng dane Null –

+0

Działa dobrze. Dzięki! – flame3

Powiązane problemy