目标C到Swift代码转换,似乎无法在Swift中正确处理字节 [英] Objective C to Swift code conversion, can't seem to treat bytes correctly in Swift

查看:160
本文介绍了目标C到Swift代码转换,似乎无法在Swift中正确处理字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款简单的Swift蓝牙心率监测器iOS App。我找到了这个伟大的教程,它有目标C码。我已将它转换为Swift,我从心率监测器获取数据。我的问题是我似乎无法在Swift中正确访问和转换字节数据。

I'm working on a simple Swift bluetooth heart rate monitor iOS App. I found this great tutorial which has objective C code. I've converted it to Swift and I'm getting data from my heart rate monitor. My problem is that I can't seem to correctly access and convert the byte data in Swift.

这是Objective C代码:

Here's the Objective C code:

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


推荐答案

const uint8_t *reportData = [data bytes];

转换为

let reportData = UnsafePointer<UInt8>(data.bytes)

然后 reportData 的类型为 UnsafePointer< UInt8> ,您可以在(目标 - )C中访问它:

Then reportData has the type UnsafePointer<UInt8> and you can access it as in (Objective-)C:

if (reportData[0] & 0x01) == 0 { ... }

接下来,

bpm = reportData[1];

在Swift中几乎相同。你必须明确地从 UInt8 转换为
UInt16 ,因为 - 与(目标 - )C - Swift不同不能在类型之间隐式转换:

is almost identical in Swift. You have to convert explicitly from UInt8 to UInt16 because – unlike (Objective-)C – Swift does not implicitly convert between types:

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 。而不是

Note that most of your variables can be declared as constants with let, instead of var. Instead of

bpm = CFSwapInt16LittleToHost(bpm)

您也可以使用 littleEndian:构造函数,对于所有整数类型,可以使用

you can alternatively use the littleEndian: constructor which is available for all integer types:

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

    // ...
}

这篇关于目标C到Swift代码转换,似乎无法在Swift中正确处理字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆