2017-05-04 3 views
0

Je suis extrêmement confus à ce sujet et je me demande si quelqu'un a des idées car je ne suis pas sûr de ce que le problème est et ma meilleure estimation est la mise en cache. Lorsque j'exécute cette application environ 95% du temps, il se connecte correctement et accède à la caractéristique d'alerte mais ne déclenche pas didUpdateValueFor. Parfois cependant quand je change, ou réinstalle l'application cela fonctionne correctement et se déclenche. Je sais que la valeur périphérique est correctement mise à jour lorsque j'ai testé sur d'autres applications. Je travaille avec un iPhone 6 et j'ai recommencé plusieurs fois. Je ne suis pas sûr de ce qui le fait fonctionner parfois et donc n'ai pas pu déboguer. Une idée ou des moyens que je peux trouver le problème?iOS Erreur de mise en cache Bluetooth?

import UIKit 
import CoreBluetooth 

class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate { 
    var manager: CBCentralManager! 
    var peripheral: CBPeripheral! 
    var devices: [CBPeripheral] = [] 

    var closestRSSI = 0 
    var alertCharacteristic: CBCharacteristic? = nil 

    let SERVICE_UUID = CBUUID(string: "06758213-258D-44B2-A577-8AE43E9DF674") 
    let ALERT_UUID = CBUUID(string: "B9FBC271-666B-4CA7-8F9C-F8E9C0223D20") 
    let BATTERY_UUID = CBUUID(string: "4D757E85-6A28-48CB-9CF5-299CB72D5AB2") 
    let FIRMWARE_UUID = CBUUID(string: "64CD5AF5-B6EE-4D46-A164-246BB197F5DA") 
    let CLIENT_CONFIG_UUID = CBUUID(string: "00002902-0000-1000-8000-00805F9B34FB") 
    var characteristicUUIDArray: [CBUUID] = [] 

    @IBOutlet weak var connectButton: UIButton! 
    @IBOutlet weak var infoLabel: UILabel! 
    @IBOutlet weak var headLabel: UILabel! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     manager = CBCentralManager(delegate: self, queue: nil) 
     infoLabel.text = "0" 
     characteristicUUIDArray = [ALERT_UUID, BATTERY_UUID, FIRMWARE_UUID] 
    } 

    @IBAction func connectButtonPressed(_ sender: Any) { 

    } 

    func centralManagerDidUpdateState(_ central: CBCentralManager) { 
     switch central.state{ 
     case .unauthorized: 
      print("Unauthorized to use BLE") 
      break 
     case .poweredOff: 
      print("Bluetooth is currently powered off") 
      break 
     case .poweredOn: 
      print("Bluetooth is ready to use") 
      manager.scanForPeripherals(withServices: [SERVICE_UUID], options: nil) 
      break 
     case .resetting: 
      print("Blueooth is resetting") 
      break 
     case .unknown: 
      print("Bluetooth is unknown") 
      break 
     case .unsupported: 
      print("Bluetooth is unsupported") 
      break 
     } 
    } 

    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { 
     print(error!) 
    } 

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { 
     print(peripheral.name ?? "Null") 
     if peripheral.name != nil{ 
      if peripheral.name! == "Watch" { 
       self.manager.stopScan() 
       self.peripheral = peripheral 
       self.peripheral.delegate = self 
       manager.connect(peripheral, options: nil) 
      } 
     } 
    } 

    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { 
     print("Disconnected") 
     manager.cancelPeripheralConnection(peripheral) 
     manager.scanForPeripherals(withServices: [SERVICE_UUID], options: nil) 
    } 

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { 
     print("\nDid Connect To \(peripheral.name!)") 
     peripheral.discoverServices([SERVICE_UUID]) 
    } 

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { 
     print("Did Discover Services") 
     for service in peripheral.services!{ 
      let thisService = service 

      if thisService.uuid == SERVICE_UUID{ 
       peripheral.discoverCharacteristics(characteristicUUIDArray, for: thisService) 
      } 
     } 
    } 

    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { 
     print("Did Discover Characteristics") 
     for charateristic in service.characteristics! { 
      let thisCharacter = charateristic 

      if thisCharacter.uuid == ALERT_UUID{ 
       print("Alert") 
       peripheral.setNotifyValue(true, for: thisCharacter) 
      } 

//   if thisCharacter.uuid == BATTERY_UUID{ 
//    print("Battery") 
//    self.peripheral.setNotifyValue(true, for: thisCharacter) 
//   } 
     } 
    } 

    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { 
     print("Did update") 
     if(characteristic.uuid == ALERT_UUID){ 
      print("Did Update Value For Alert") 
      let content = String(data: characteristic.value!, encoding: String.Encoding.utf8) 
      let value = content?.components(separatedBy: ",") 
      let warning = Int(value![0]) 
      infoLabel.text = String(warning!) 
     } 

     if(characteristic.uuid == BATTERY_UUID){ 
      print("Did Update Value For Battery") 
     } 
    } 
} 
+0

Je pense que je suis sur quelque chose. Si j'ajoute un point d'arrêt à la caractéristique didDiscover pour l'alerte et l'attendez un instant, il semble fonctionner à chaque fois. Pourrait-il y avoir un problème de synchronisation lors de la définition de la caractéristique à notifier? – Ubarjohade

+0

Tant que j'ai un point d'arrêt dans le thisCharacter.uuid == ALERT_UUID il se mettra à jour après avoir atteint CV. Ceci est un problème frustrant pour quelqu'un de nouveau à iOS – Ubarjohade

Répondre

0

Donc je crois que c'était une erreur de condition de concurrence. En enveloppant chaque caractéristique dans un délai, le problème a été résolu. Voici ce que j'ai changé. Donc, je crois que c'était une erreur de condition de course. En enveloppant chaque caractéristique dans un délai, le problème a été résolu. Voici ce que j'ai changé. Je ne sais pas pourquoi cela le corrige, mais si quelqu'un a des idées que j'aimerais entendre pourquoi c'est

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { 
    print("Did Discover Characteristics") 
    for charateristic in service.characteristics! { 
     let thisCharacter = charateristic 

     if thisCharacter.uuid == ALERT_UUID{ 
      print("Alert") 
      DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3), execute: { 
       peripheral.setNotifyValue(true, for: thisCharacter) 
      }) 
     } 

     if thisCharacter.uuid == BATTERY_UUID{ 
      print("Battery") 
      DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3), execute: { 
       peripheral.setNotifyValue(true, for: thisCharacter) 
      }) 
     } 
    } 
}