2014-11-05 2 views
1

Я начинаю проект создания приложения iOS для связи с устройством через BLE. Будучи новым усилием, я пытаюсь сделать это, если возможно, Swift. Интерфейс использует GATT и существующий набор настраиваемых структур сообщений. Я добираюсь до точки, где у меня есть данные от BLE в объекте NSData. Я бы хотел, чтобы он использовал его или напрямую преобразовал в структуру моего сообщения довольно общим образом.Преобразование байт NSData в пользовательский объект

Я знаю, что я могу извлечь данные вручную либо из массива байтов из объекта NSData, либо с помощью NSInputStream. В то время как это работает, это может быть проблемой обслуживания, и в интерфейсе есть несколько различных сообщений.

Есть ли более простые способы сделать это?

Я бы желал создать структуры сообщений в Objective-C и делать кастинг там, но мои знания Objective-C не намного лучше, чем мои знания Swift.

Ниже приведен пример кода, который я играл на своей игровой площадке. Все работает так, как ожидалось.

func getBytesFromNSData(data: NSData, start: Int) -> [UInt8] { 
    let count = data.length/sizeof(UInt8) 
    let remaining = count - start 
    let range = NSMakeRange(start, remaining) 
    var dataArray = [UInt8](count: remaining, repeatedValue: 0) 
    data.getBytes(&dataArray, range: range) 
    return dataArray 
} 

class TestObject { 
    var a: Byte 
    var b: Byte 

    init() { 
     a = 0x01 
     b = 0x02 
    } 

    init(data: NSData) { 
     let dataBytes = getBytesFromNSData(data, 0) 
     a = Byte(dataBytes[0]) 
     b = Byte(dataBytes[1]) 
    } 

    func populateFromStream(data: NSData) { 
     var stream = NSInputStream(data: data) 
     stream.open() 
     var bytesRead = stream.read(&a, maxLength: 1) 
     println("\(bytesRead)") 

     bytesRead = stream.read(&b, maxLength: 1) 
     println("\(bytesRead)") 
    } 

    func toArray() -> [Byte] { 
     var result = [Byte](count: 2, repeatedValue: 0) 
     result[0] = a 
     result[1] = b 

     return result 
    } 
} 

let test = TestObject() 
let testArray = test.toArray() 
let length = testArray.count 
let testData = NSData(bytes: testArray, length: length) 
println("\(testData)") 

let testIn = [ Byte(0x0d), Byte(0x0e) ] 
let testDataIn = NSData(bytes: testIn, length: testIn.count) 
println("\(testDataIn)") 

let testConstructor = TestObject(data: testDataIn) 

var testObject = TestObject() 
testObject.populateFromStream(testDataIn) 
+0

Поймите, что вряд ли кто-нибудь знает, какие структуры данных GATT подразумевает. Но вид разборки, который вы, по-видимому, хотите сделать, вероятно, лучше всего выполнять в чистом C, либо путем определения 'struct' для наложения данных, либо путем считывания отдельных байтов и сборки в желаемую форму. –

+0

Вот такой вывод, к которому я иду, но я надеялся, что у кого-то может быть другой ответ. Чтение отдельных байтов не сложно в Swift, это просто утомительно. –

+0

Ваш лучший выбор - как-то придумать стандартизованный «стиль», с которым вы справляетесь со всем, против ad-hoc.Например, напишите утилиты, которые дают вам 'int' или' double' или что-то еще, начиная с заданного смещения в объекте NSData. Затем записывайте последовательности тех, которые перемещаются в/из ваших внутренних структур. Держите сложные вычисления смещения/длины до минимума и держите их всех в одном месте. –

ответ

0

Я нашел метод, который довольно общий, который может работать в некоторых случаях.

  1. Создать Objective-C езду заголовок
  2. Создать структуру данных в виде структуры Objective-C
  3. Импорта заголовок со структурой данных в обводном заголовок
  4. Если предположить, что у вас есть структура называется Foo и объект NSData называется rawData:

Используйте следующий код, чтобы получить CAST указатель.

let structureSize = sizeof(Foo) 
var myObject = UnsafeMutablePointer<Foo>.alloc(1).memory 
rawData.getbytes(&myObject, length: structureSize) 

Это не будет работать во всех случаях и, к сожалению, работает в моем конкретном случае. Конкретные проблемы, которые я нашел, следующие:

  • Структура Objective-C выравнивается по слову. Если ваша структура неправильно привязана к границам работы, вы можете иметь неправильный размер. (что-то, с чем я столкнулся в моем конкретном интерфейсе)
  • Если вы и имеете дело с системой, которая не отправляет данные в том же порядке, который вы ожидаете, это не будет обрабатывать любые преобразования порядка байтов, которые все равно должны быть и структура, возможно, потребуется переупорядочить для компенсации. Эта работа может отрицать любую экономию от этого метода.

Это самый сжатый метод, который я нашел, если это происходит с вашими конкретными форматами сообщений.

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