[英]Create ENUM from NSData
Is there any way to create a ENUM from an NSData object ? 有什么方法可以从NSData对象创建ENUM吗? I receive an NSData from a bluetooth device, to let it more readable i was thinking to use ENUM.
我从蓝牙设备收到了NSData,为了让它更具可读性,我正在考虑使用ENUM。
my code right now : 我的代码现在:
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")
}
You can do this, provided you have a predefined set of possible values for your messages: 只要您为消息提供了一组预定义的可能值,就可以这样做:
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")
}
}
Assuming all your codes are 2 bytes, then they can be encoded as a UInt16
, which is easily raw-convertible. 假设您的所有代码均为2个字节,则可以将它们编码为
UInt16
,这很容易进行原始转换。 You just need to do a little math to convert the NSData into a 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")
}
(As Kenneth Bruno notes, you could also just use a UnsafePointer<UInt16>
here rather than doing the math by hand. That would be fine; maybe even better.) (正如Kenneth Bruno指出的,您也可以在此处使用
UnsafePointer<UInt16>
而不是手工进行数学运算。那会很好;甚至更好。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.