从字节中获取字符串(Corebluetooth,Swift)
Posted
技术标签:
【中文标题】从字节中获取字符串(Corebluetooth,Swift)【英文标题】:Getting a String from a byte (Corebluetooth, Swift) 【发布时间】:2020-05-13 09:13:31 【问题描述】:只是为了看看是否有人可以帮助我解决一些 BLE 问题。我正在尝试制作一个从划船机中获取内容的应用程序,但我不知道如何将字节转换为字符串?很难解释,但这是我的 VC:
import UIKit
import CoreBluetooth
let rowerServiceCBUUID = CBUUID(string: "CE060000-43E5-11E4-916C-0800200C9A66")
let characteristic1CBUUID = CBUUID(string: "CE060031-43E5-11E4-916C-0800200C9A66")
let characteristic2CBUUID = CBUUID(string: "2AD1")
class HRMViewController: UIViewController
@IBOutlet weak var heartRateLabel: UILabel!
@IBOutlet weak var bodySensorLocationLabel: UILabel!
var centralManager: CBCentralManager!
var pmPeripheral: CBPeripheral!
var wattValue: Int!
override func viewDidLoad()
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil)
// Make the digits monospaces to avoid shifting when the numbers change
heartRateLabel.font = UIFont.monospacedDigitSystemFont(ofSize: heartRateLabel.font!.pointSize, weight: .regular)
func onHeartRateReceived(_ heartRate: Int)
heartRateLabel.text = String(heartRate)
print("BPM: \(heartRate)")
extension HRMViewController: CBCentralManagerDelegate
func centralManagerDidUpdateState(_ central: CBCentralManager)
print("Central state update")
if central.state != .poweredOn
print("Central is not powered on")
else
print("Central scanning for", rowerServiceCBUUID);
centralManager.scanForPeripherals(withServices: [rowerServiceCBUUID],
options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
print(peripheral)
peripheral.delegate = self
pmPeripheral = peripheral
pmPeripheral.delegate = self
centralManager.stopScan()
centralManager.connect(pmPeripheral!)
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
print("Connected!")
pmPeripheral.discoverServices(nil)
extension HRMViewController: CBPeripheralDelegate
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)
guard let services = peripheral.services else return
for service in services
print(service)
print(service.characteristics ?? "characteristics are nil")
peripheral.discoverCharacteristics(nil, for: service)
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?)
guard let characteristics = service.characteristics else return
for characteristic in characteristics
print(characteristic)
if characteristic.properties.contains(.read)
print("\(characteristic.uuid): properties contains .read")
if characteristic.properties.contains(.notify)
print("\(characteristic.uuid): properties contains .notify")
peripheral.readValue(for: characteristic)
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic,
error: Error?)
switch characteristic.uuid
case characteristic1CBUUID:
let bodySensorLocation = bodyLocation(from: characteristic)
bodySensorLocationLabel.text = bodySensorLocation
default:
print("Unhandled Characteristic UUID: \(characteristic.uuid)")
private func bodyLocation(from characteristic: CBCharacteristic) -> String
guard let characteristicData = characteristic.value,
let byte = characteristicData.first else return "Error"
switch byte
case 0: return "0"
case 1: return "1"
case 2: return "2"
case 3: return "3"
case 4: return "4"
case 5: return "5"
case 6: return "6"
case 7: return "7"
case 8: return "8"
default:
return "Reserved for future use"
特别是最底部的文本是我卡住的地方,每个 Corebluetooth 指南都将数字交换为文本,但我的是一个字符串数组(如下所示:https://youtu.be/rXDCBVQXdbg)
我被困住了,不知道从这里去哪里。对此的任何帮助将不胜感激!
【问题讨论】:
您需要查看您正在使用的特征的定义。如果是字符串数据,则可以使用String(data: data, encoding .utf8)
【参考方案1】:
从您使用的 UUID 来看,您目前关注的是Concept2 Performance Monitor Bluetooth Smart Communications Interface Definition 第 11 页上记录的C2 划船一般状态特征。
文档说该消息将由 19 个字节组成:
字节 0:经过时间 Lo(0.01 秒 lsb) 字节 1:中间经过的时间 字节 2:经过时间高 字节 3:距离 Lo (0.1 m lsb) 字节 4:中距离 字节 5:距离高 字节 6:锻炼类型(枚举) ...经过的时间存储在 3 个字节中:字节 0 是最低有效字节 (LSB),然后是中字节和高字节。单位为0.01s。所以要获得秒数,必须除以 100。
距离的存储方式类似。单位是0.1m。
锻炼类型在字节 6 中作为枚举给出。所以不包含文本。只是一个数字代码。
要对其进行解码,请使用如下代码。函数onRowingGeneralStatusUpdate(for:)
替换了你容易混淆的函数bodyLocation(from:)
:
func onRowingGeneralStatusUpdate(characteristic: CBCharacteristic)
guard let data = characteristic.value else return
// elapsed time in sec
let elapsedTime: Double = Double(Int(data[0]) + 256 * Int(data[1]) + 65536 * Int(data[2])) / 100.0
// distance in m
let distance: Double = Double(Int(data[3]) + 256 * Int(data[4]) + 65536 * Int(data[5])) / 10.0
let workout: String = workoutType(for: data[6])
func workoutType(for code: UInt8) -> String
switch code
case 0:
return "Just row, no splits"
case 1:
return "Just row, splits"
case 2:
return "Fixed dist, no splits"
case 3:
return "Fixed dist, splits"
case 4:
return "Fixed time, no splits"
case 5:
return "Fixed time, splits"
case 6:
return "Fixed time, interval"
case 7:
return "Fixed dist, interval"
case 8:
return "Variable, interval"
case 9:
return "Variable, undef rest, interval"
case 10:
return "Fixed, calorie"
case 11:
return "Fixed, watt-minutes"
case 12:
return "Fixed cals, interval"
default:
return ""
【讨论】:
我得说,谢谢!没有你的回答,我仍然会困惑地坐在这里。 (它被称为 bodylocation,因为我正在关注人力资源指南) 嘿,呃,你能帮我做点什么吗?每当我打印出锻炼、距离和经过的时间时,每次打印时它都会打印出 Error, 120856.02, 1083899.8。你知道我需要做什么来修复它吗? 听起来好像接收到的数据根本不符合预期的描述。可能是错误的特征或其他一些混淆?以上是关于从字节中获取字符串(Corebluetooth,Swift)的主要内容,如果未能解决你的问题,请参考以下文章
iPhone 5C/5S 上的 CoreBluetooth:收到的数据损坏
如何获取/查找 CoreBluetooth.Framework?