Я начинаю проект создания приложения 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)
Поймите, что вряд ли кто-нибудь знает, какие структуры данных GATT подразумевает. Но вид разборки, который вы, по-видимому, хотите сделать, вероятно, лучше всего выполнять в чистом C, либо путем определения 'struct' для наложения данных, либо путем считывания отдельных байтов и сборки в желаемую форму. –
Вот такой вывод, к которому я иду, но я надеялся, что у кого-то может быть другой ответ. Чтение отдельных байтов не сложно в Swift, это просто утомительно. –
Ваш лучший выбор - как-то придумать стандартизованный «стиль», с которым вы справляетесь со всем, против ad-hoc.Например, напишите утилиты, которые дают вам 'int' или' double' или что-то еще, начиная с заданного смещения в объекте NSData. Затем записывайте последовательности тех, которые перемещаются в/из ваших внутренних структур. Держите сложные вычисления смещения/длины до минимума и держите их всех в одном месте. –