2016-02-26 45 views
1

有什麼辦法從NSData對象創建ENUM嗎? 我從藍牙設備收到一個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

你想打的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