2016-02-26 3 views
1

Есть ли способ создать ENUM из объекта NSData? Я получаю NSData с устройства bluetooth, чтобы он был более читаемым, я думал использовать ENUM.Создать ENUM от NSData

мой код прямо сейчас:

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

Вы хотите сделать перечисление из NSData ? Вы не можете, NSData не конвертируется в любой литерал или не соответствует протоколу RawRepresentable. – JAL

ответ

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") 
    } 
} 
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") 
} 

(Как отмечает Кеннет Бруно, вы также можете просто использовать UnsafePointer<UInt16> здесь, а не делать математику вручную, что было бы хорошо,.. Может быть, даже лучше)

+0

Добавление функции 'init? '- хорошая идея. Я не делал этого в своем ответе ради ясности, но это приятно иметь для краткости. – ColGraff

 Смежные вопросы

  • Нет связанных вопросов^_^