Is it possible to convert an array [Any] to Nsdata?

Asked

Viewed 79 times

1

I need to generate an Nsdata variable from an array that allows any type of data.

I tried the following tickle, which didn’t work:

let a0 : Int8 = 3
let a1 : UInt16 = 231
let a2 : Int = 1024

let array : [Any] = [a2, a1, a0]
var data = NSData(bytes: array, length: array.count)

He returns to me the following:

array: [1024, 231, 3]

date: <000400>

When I try to convert an array of a data type only, the conversion occurs smoothly.

let arrayUInt8 : [UInt8] = [255, 0x02, 3]

let dataUInt8 = NSData(bytes: arrayUInt8, length: arrayUInt8.count)

Return me the following:

arrayUInt8: [255, 2, 3]

dataUInt8: < ff0203>

Thanks in advance.

  • @Leodabus, in my application I need the fields with the correct sizes.

2 answers

1


You should first extend Integertype to be able to extract your bytes in Nsdata form using getBytes and use dynamicType sizeof() to determine the byte length:

extension IntegerType {
    var data: NSData {
        var source = self
        return NSData(bytes: &source, length: sizeof(self.dynamicType))
    }
}

With this done Voce must create a method to concatenate your data before sending:

func getDataToSend(first: Int8,_ second: UInt16,_ third: Int) -> NSData {
    let mutableData = NSMutableData()
    mutableData.appendData(first.data)
    mutableData.appendData(second.data)
    mutableData.appendData(third.data)
    return mutableData
}

And Voce can also extend Nsdata to make it easier to extract your elements from it:

extension NSData {
    var getElements:(first: Int8, second: UInt16, third: Int) {
        var resultInt8: Int8 = 0
        var resultUInt16: UInt16 = 0
        var resultInt: Int = 0
        getBytes(&resultInt8, range: NSRange(location: 0, length: sizeof(Int8)))
        getBytes(&resultUInt16, range: NSRange(location: 1, length: sizeof(UInt16)))
        getBytes(&resultInt, range: NSRange(location: 3, length: sizeof(Int)))
        return (resultInt8, resultUInt16, resultInt)
    }
}

Testing:

let a0: Int8 = 3
let a1: UInt16 = 231
let a2: Int = 1024

let dataToSend = getDataToSend(a0, a1, a2)
print(dataToSend.length) // 11

let elementsFromData = dataToSend.getElements   // (.0 3, .1 231, .2 1024)
let firstElement = elementsFromData.first       // 3
let secondElement = elementsFromData.second     // 231
let thirdElement = elementsFromData.third       // 1024
  • Leo, I fixed my answer again, there was a detail missing, now it’s compiling. You see some difference in using one or the other answer?

  • You can do as you see fit. I just think Voce should use sizeof() instead of putting the language manually

  • 1

    Okay, I didn’t know about the use of Xtension. Thank you for your attention!!!

  • @Arubu Xtensions are the best way to pack your code and make it available anywhere in your app

0

I solved my problem using Nsmutabledata this way:

var a0 : Int8 = 3
var a1 : UInt16 = 231
var a2 : Int = 1024

let data = NSMutableData(bytes: &a0, length: 1)
    data.appendBytes(&a1, length: 2)
    data.appendBytes(&a2, length: 8)

I don’t know if this is the best way, but it works!!! If anyone has a better answer add here I change the answer accepted!!

  • Your code doesn’t even compile for me "Cannot Convert value of type Int8 to expected argument type Unsafepointer<Void>

  • If Voce changes the order of the elements, as Voce will know where Voce stored Int, Uint16 or Int8 ?

  • I can even show you how Voce should do this but I have no idea how Voce would do to control the content of your mutable data

  • @Leodabus I changed the code, is compiling, tested on the playground. I will not change the order of the elements, will always stay like this. I need to assemble the data to send via bluetooth. As I said, this code worked for my purpose, surely there may be a better way to do this.

  • And another thing the length of the Int is 8 bytes (Int64) and not 4

  • That’s right!!! I forgot to change A0 to variable, now compile compile.

  • Compiling was not the only problem Oce was append only the first 4 bytes of Int and discarding the other 4.

  • @Leodabus I took advantage and fixed this problem too.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.