Trouble converting NSData Objective-C code to Swift

亡梦爱人 提交于 2019-12-12 05:32:01

问题


I've been having issues converting an Objective-C snippet to Swift that uses NSData and CoreBluetooth. I have looked at this question and a couple others dealing with NSData in Swift but haven't had any success.

Objective-C Snippet:

- (CGFloat) minTemperature
{
    CGFloat result = NAN;
    int16_t value = 0;

    // characteristic is a CBCharacteristic
    if (characteristic) { 
        [[characteristic value] getBytes:&value length:sizeof (value)];
        result = (CGFloat)value / 10.0f;
    }
    return result;
}

What I have so far in Swift (not working):

func minTemperature() -> CGFloat {
    let bytes = [UInt8](characteristic?.value)
    let pointer = UnsafePointer<UInt8>(bytes)
    let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 }
     value = Int16(fPointer.pointee)

    result = CGFloat(value / 10) // not correct value

    return result
}

Does the logic look wrong here? Thanks!


回答1:


One error is in

let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 }

because the rebound pointer $0 is only valid inside the closure and must not be passed to the outside. Also the capacity should be 1 for a single Int16 value. Another problem is the integer division in

result = CGFloat(value / 10)

which truncates the result (as already observed by the4kman).

Creating an [UInt8] array from the data is not necessary, the withUnsafeBytes() method of Data can be used instead.

Finally you could return nil (instead of "not a number") if no characteristic value is given:

func minTemperature() -> CGFloat? {
    guard let value = characteristic?.value else {
        return nil
    }
    let i16val = value.withUnsafeBytes { (ptr: UnsafePointer<Int16>) in
        ptr.pointee
    }
    return CGFloat(i16val) / 10.0
}



回答2:


You should make the return value optional and check if characteristic is nil in the beginning with a guard. You should also explicitly convert the value to CGFloat, then divide it by 10.

func minTemperature() -> CGFloat? {
    guard characteristic != nil else {
        return nil
    }

    let bytes = [UInt8](characteristic!.value)
    let pointer = UnsafePointer<UInt8>(bytes)
    let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 }
    let value = Int16(fPointer.pointee)

    result = CGFloat(value) / 10

    return result
}


来源:https://stackoverflow.com/questions/45287488/trouble-converting-nsdata-objective-c-code-to-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!