有没有办法从NSData对象创建ENUM? 我从蓝牙设备收到一个NSData,让它更具可读性我想用ENUM。
我现在的代码:
let data = NSData(bytes: [0x00, 0x12] as [UInt8], length: 2)
let initData = NSData(bytes: [0xa2,0x12] as [UInt8], length: 2)
let openedData = NSData(bytes: [0xa1,0x12] as [UInt8], length: 2)
let alreadyOpenedData = NSData(bytes: [0xa1,0x13] as [UInt8], length: 2)
let finishedData = NSData(bytes: [0xa3,0x12] as [UInt8], length: 2)
switch data{
case openedData:
print("opened")
break
case alreadyOpenedData:
print("alreadyOpened")
break
case initData:
print("ini")
break
case finishedData:
print("finished")
default:
print("error")
}
答案 0 :(得分:3)
如果您的消息有一组预定义的可能值,则可以执行此操作:
import Foundation
let data = NSData(bytes: [0xa2, 0x12] as [UInt8], length: 2)
enum Data: UInt16 {
case Init = 0x12a2
case Opened = 0x12a1
case AlreadyOpened = 0x13a1
case Finished = 0x12a3
}
func convert(data: NSData) -> UInt16? {
guard data.length == 2 else { return nil } // with thanks to Rob Napier
return UnsafePointer<UInt16>(data.bytes).memory
}
if let convertedValue = convert(data),
let convertedData = Data(rawValue: convertedValue) {
switch convertedData {
case .Opened:
print("opened")
case .AlreadyOpened:
print("alreadyOpened")
case .Init:
print("ini")
case .Finished:
print("finished")
}
}
答案 1 :(得分:3)
假设您的所有代码都是2个字节,那么它们可以编码为UInt16
,这很容易进行原始转换。您只需要做一些数学运算就可以将NSData转换为UInt16
。
enum State: UInt16 {
case Init = 0xa212
case Opened = 0xa112
case AlreadyOpened = 0xa113
case Finished = 0xa312
init?(data: NSData) {
guard data.length == 2 else { return nil }
let bytes = UnsafePointer<UInt8>(data.bytes)
let rawValue = UInt16(bytes[0]) << 8 + UInt16(bytes[1])
self.init(rawValue: rawValue)
}
}
if let state = State(data: data) {
switch state {
case .Opened:
print("opened")
break
case .AlreadyOpened:
print("alreadyOpened")
break
case .Init:
print("ini")
break
case .Finished:
print("finished")
}
} else {
print("error")
}
(正如Kenneth Bruno指出的那样,你也可以在这里使用UnsafePointer<UInt16>
而不是手工数学。那没关系;甚至可能更好。)