我正在开发一个简单的Swift蓝牙心率监控器iOS应用程序。我发现了这很棒的教程,它有目标C代码。我已经把它转换成Swift了,我从我的心率监测器得到数据。我的问题是,我似乎无法正确地访问和转换Swift中的字节数据。
以下是目标C代码:
// Instance method to get the heart rate BPM information
- (void) getHeartBPMData:(CBCharacteristic *)characteristic error:(NSError *)error
{
// Get the Heart Rate Monitor BPM
NSData *data = [characteristic value]; // 1
const uint8_t *reportData = [data bytes];
uint16_t bpm = 0;
if ((reportData[0] & 0x01) == 0) { // 2
// Retrieve the BPM value for the Heart Rate Monitor
bpm = reportData[1];
}
else {
bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1])); // 3
}
// Display the heart rate value to the UI if no error occurred
if( (characteristic.value) || !error ) { // 4
self.heartRate = bpm;
self.heartRateBPM.text = [NSString stringWithFormat:@"%i bpm", bpm];
self.heartRateBPM.font = [UIFont fontWithName:@"Futura-CondensedMedium" size:28];
[self doHeartBeat];
self.pulseTimer = [NSTimer scheduledTimerWithTimeInterval:(60. / self.heartRate) target:self selector:@selector(doHeartBeat) userInfo:nil repeats:NO];
}
return;
}以下是Swift代码:
func peripheral(peripheral: CBPeripheral!,
didUpdateValueForCharacteristic characteristic: CBCharacteristic!,
error: NSError!) -> String
{
// Get the Heart Rate Monitor BPM
var data = characteristic.value
var reportData = data.bytes
var bpm : UInt16
var rawByte : UInt8
var outputString = ""
rawByte = UInt8(reportData[0])
bpm = 0
if ((rawByte & 0x01) == 0) { // 2
// Retrieve the BPM value for the Heart Rate Monitor
bpm = UInt16( reportData[4] )
}
else {
bpm = CFSwapInt16LittleToHost(UInt16(reportData[1]))
}
outputString = String(bpm)
return outputString
}发布于 2015-01-14 17:39:32
const uint8_t *reportData = [data bytes];翻译成
let reportData = UnsafePointer<UInt8>(data.bytes)然后,reportData具有UnsafePointer<UInt8>类型,您可以访问它,如(Objective)中所示:
if (reportData[0] & 0x01) == 0 { ... }下一首,
bpm = reportData[1];在斯威夫特里几乎是一样的。您必须显式地将UInt8转换为UInt16,因为--与(Objective)C- Swift不同,Swift不会在类型之间隐式转换:
bpm = UInt16(reportData[1]) 把它放在一起:
func getHeartBPMData(characteristic: CBCharacteristic!) {
let data = characteristic.value
let reportData = UnsafePointer<UInt8>(data.bytes)
var bpm : UInt16
if (reportData[0] & 0x01) == 0 {
bpm = UInt16(reportData[1])
} else {
bpm = UnsafePointer<UInt16>(reportData + 1)[0]
bpm = CFSwapInt16LittleToHost(bpm)
}
// ...
}请注意,可以用let而不是var将大多数变量声明为常量。而不是
bpm = CFSwapInt16LittleToHost(bpm)您也可以使用适用于所有整数类型的littleEndian:构造函数:
bpm = UInt16(littleEndian: bpm)Swift 3/4的更新:
func getHeartBPMData(characteristic: CBCharacteristic) {
guard let reportData = characteristic.value else {
return
}
let bpm : UInt16
if (reportData[0] & 0x01) == 0 {
bpm = UInt16(reportData[1])
} else {
bpm = UInt16(littleEndian: reportData.subdata(in: 1..<3).withUnsafeBytes { $0.pointee } )
}
// ...
}https://stackoverflow.com/questions/27947626
复制相似问题