首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >目标C到Swift代码转换,似乎无法正确处理Swift中的字节

目标C到Swift代码转换,似乎无法正确处理Swift中的字节
EN

Stack Overflow用户
提问于 2015-01-14 16:20:39
回答 1查看 828关注 0票数 3

我正在开发一个简单的Swift蓝牙心率监控器iOS应用程序。我发现了很棒的教程,它有目标C代码。我已经把它转换成Swift了,我从我的心率监测器得到数据。我的问题是,我似乎无法正确地访问和转换Swift中的字节数据。

以下是目标C代码:

代码语言:javascript
复制
// 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代码:

代码语言:javascript
复制
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
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-14 17:39:32

代码语言:javascript
复制
const uint8_t *reportData = [data bytes];

翻译成

代码语言:javascript
复制
let reportData = UnsafePointer<UInt8>(data.bytes)

然后,reportData具有UnsafePointer<UInt8>类型,您可以访问它,如(Objective)中所示:

代码语言:javascript
复制
if (reportData[0] & 0x01) == 0 { ... }

下一首,

代码语言:javascript
复制
bpm = reportData[1];

在斯威夫特里几乎是一样的。您必须显式地将UInt8转换为UInt16,因为--与(Objective)C- Swift不同,Swift不会在类型之间隐式转换:

代码语言:javascript
复制
bpm = UInt16(reportData[1]) 

把它放在一起:

代码语言:javascript
复制
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将大多数变量声明为常量。而不是

代码语言:javascript
复制
bpm = CFSwapInt16LittleToHost(bpm)

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

代码语言:javascript
复制
bpm = UInt16(littleEndian: bpm)

Swift 3/4的更新:

代码语言:javascript
复制
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 } )
    }

    // ...
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27947626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档