简体   繁体   English

从NSData创建ENUM

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM