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

1

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

I tried the following code, which did not 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)

It returns me the following:

  

array: [1024, 231, 3]

     

data: < 000400 >

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

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

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

I get the following:

  

arrayUInt8: [255, 2, 3]

     

dataUInt8: < ff0203 >

Thank you in advance.

    
asked by anonymous 12.01.2016 / 11:11

2 answers

1

You should first extend IntegerType to extract its bytes in NSData form using getBytes and use sizeof () of dynamicType to determine the length of the byte:

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

With this done you should 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 you 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
    
19.01.2016 / 17:28
0

I solved my problem using NSMutableData like this:

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 do not know if this is the best way, but it works !!! If someone has a better answer add here I change the accepted answer !!

    
18.01.2016 / 19:30