从NSData创建ENUM

时间:2016-02-26 15:06:58

标签: ios swift enums bluetooth nsdata

有没有办法从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")
}

2 个答案:

答案 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>而不是手工数学。那没关系;甚至可能更好。)