ios - 从 ble swift 读取值的问题
问题描述
我正在做一个 ble 应用程序,当我尝试从 ble 设备读取值时,我需要从中获取一些值,它第一次返回 nil,当我返回并再次执行时,它返回值。在下面的代码中,我试图获取固件版本和电池的值。我第一次运行代码,它始终为固件版本和电池返回值返回 nil。请帮助弄清楚为什么我在第一次执行时没有收到固件版本的值。
这是我的代码
extension SearchDeviceViewController: CBCentralManagerDelegate, CBPeripheralDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unknown:
print("central.state is .unknown")
case .resetting:
print("central.state is .resetting")
case .unsupported:
print("central.state is .unsupported")
case .unauthorized:
print("central.state is .unauthorized")
case .poweredOff:
print("central.state is .poweredOff")
case .poweredOn:
print("central.state is .poweredOn")
centralManager.scanForPeripherals(withServices: nil)
@unknown default:
print("\(central.state)")
}
}
//establish a connection with detected BLE device
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
var dataFound = 0
for peripheralsFound in peripherals {
if peripheral.identifier == peripheralsFound.identifier {
dataFound = 1
}
}
if dataFound == 0 && peripheral.name != nil {
if !deviceIds.contains(peripheral.identifier.uuidString) {
peripherals.append(peripheral)
tblViewDeviceList.reloadData()
}
}
}
//On successful connection, request for all the services available in the BLE device
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("connected")
selectedPeripheral.discoverServices(nil)
}
//Request all the characteristics available in each services
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
print(4)
var count = 1
if let servicePeripheral = selectedPeripheral.services as [CBService]? { //get the services of the perifereal
for service in servicePeripheral {
//Then look for the characteristics of the services
if service.uuid.uuidString == "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" || service.uuid.uuidString == "180F" {
peripheral.discoverCharacteristics(nil, for: service)
} else {
if count == 1 {
Alert.showAlertView(withTitle: "", withMessage: "Invalid device")
count = count + 1
}
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
print("5")
if let characterArray = service.characteristics as [CBCharacteristic]? {
for cc in characterArray {
myCharacteristic = cc //saved it to send data in another function.
if cc.uuid.uuidString == "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" {
writeValue()
} else {
peripheral.readValue(for: cc) //to read the value of the characteristic
peripheral.setNotifyValue(true, for: myCharacteristic)
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
print("7")
print(characteristic)
if characteristic.uuid.uuidString == "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" {
if let readValue = characteristic.value {
if let datastring = NSString(data: readValue, encoding: String.Encoding.utf8.rawValue) {
self.firmware = datastring as String
}
}
}
if characteristic.uuid.uuidString == "2A19" {
if let readValue = characteristic.value {
let battery = readValue.compactMap({ String(format: "%02x", $0) }).joined()
if battery < "60" {
self.batteryStatus = "CHANGE"
} else if battery == "" {
self.batteryStatus = ""
} else {
self.batteryStatus = "OK"
}
if self.firmware != "" && battery != "" {
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let popupVC = storyboard.instantiateViewController(withIdentifier: "DeviceDetailsViewController") as! DeviceDetailsViewController
popupVC.deviceCount = defaults.integer(forKey: "devicesAdded")
popupVC.isNewDevice = true
popupVC.peripheralName = self.selectedPeripheral.name!
popupVC.deviceUUID = self.selectedPeripheral.identifier.uuidString
popupVC.fromSearch = true
popupVC.firmWare = self.firmware
popupVC.batteryStatus = self.batteryStatus
popupVC.modalPresentationStyle = .fullScreen
popupVC.modalTransitionStyle = .coverVertical
self.present(popupVC, animated: true, completion: nil)
}
}
}
}
func writeValue() {
print("8")
//Do something
let setCmnd = "GET_FW_VERSION"
let dataToSend: Data = setCmnd.data(using: String.Encoding.utf8)!
selectedPeripheral.writeValue(dataToSend, for: myCharacteristic, type: CBCharacteristicWriteType.withResponse)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
}
}
解决方案
推荐阅读
- python - 如何解决 django.core.exceptions.ImproperlyConfigured:应用程序标签不是唯一的,重复:帐户 django 1.5
- scala - 在 Scala 中实例化赋值运算符两侧的对象;它是如何工作的
- codeception - 如何为 Codeception 中的失败测试增加 traceLength?
- reactjs - 反应中的“在渲染中调用 setState 会导致无限循环”
- android - 用另一个应用程序无缝替换一个应用程序
- parsing - 我应该使用什么生产规则来减少自下而上的解析?
- r - 使用 R 从 Outlook 中的邮件中下载多个附件
- python - Pandas 拆分句子和标签短语以执行 BIO 标记
- javascript - 函数通过参数决定返回类型
- apache - 重定向指令是否覆盖配置的别名