2017-05-04 104 views
0

我對這件事感到非常困惑,不知道是否有人有任何想法,因爲我不確定問題是什麼,我最好的猜測是緩存。當我運行這個應用程序時,大約95%的時間會正確連接並訪問警報特性,但不會觸發didUpdateValueFor。有時候,當我更改或重新安裝應用程序時,它可以正常工作並觸發。我知道外設值正在正確更新,因爲我在其他應用上測試過。我正在使用iPhone 6,並且我已經多次重新啓動。我不確定什麼會導致它有時會起作用,從而無法進行調試。任何想法或方法我可以找到問題?iOS藍牙緩存錯誤?

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

我認爲我的東西。如果我爲alert添加一個斷點,並讓它稍等一會,它似乎每次都能正常工作。在設置要通知的特徵時是否會遇到一些計時問題? – Ubarjohade

+0

只要我在thisCharacter.uuid == ALERT_UUID中有一個斷點,它會在我打開簡歷後更新。對於一個新來ios的人來說,這是一個令人頭疼的問題 – Ubarjohade

回答

0

所以我相信這是一個競爭條件錯誤。通過在延遲中包裝每個特性,問題得到解決。這是我改變的。所以我認爲這是一個競爭條件錯誤。通過在延遲中包裝每個特性,問題得到解決。這是我改變的。我不確定爲什麼這個修復它,但如果任何人有任何想法,我很高興聽到爲什麼這是

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