0

I have this struct:

struct MessageRandomWords {
        let message = MessageType.kMessageTypeRandomWords
        let randomWords : Array<Array<String>>
    }

I'm trying to convert this struct to NSDate by doing this:

    var message = MessageRandomWords(randomWords: self.words)
    let data = NSData(bytes: &message, length: sizeof(MessageRandomWords))

But when i'm trying to convert this back to the original struct:

var messageRandomWords : MessageRandomWords?
                data.getBytes(&messageRandomWords, length: sizeof(MessageRandomWords))
                if let messageRandomWords = messageRandomWords {

}

I got a BAD_ACCESS erro on the if let statement. Where is the problem?

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
Max_Power89
  • 1,710
  • 1
  • 21
  • 38

1 Answers1

3

Based on this answer: Swift structs to NSData and back I wrote this solution:

struct MessageRandomWords {
    let message = MessageType.kMessageTypeRandomWords
    var data : NSData?
    var name: String

    struct ArchivedPacket {
        let message = MessageType.kMessageTypeRandomWords
        var dataLength : Int64
        var nameLength : Int64
    }

    func archive() -> NSData {
        var archivedPack = ArchivedPacket(dataLength: Int64(self.data!.length), nameLength: Int64(self.name.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)))
        var metaData = NSData(bytes: &archivedPack, length: sizeof(ArchivedPacket))
        let archiveData = NSMutableData(data: metaData)
         archiveData.appendData(name.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!)
        archiveData.appendData(data!)
        return archiveData
    }

    static func unarchive(data : NSData!) -> MessageRandomWords {
        var archivedPacket = ArchivedPacket(dataLength: 0, nameLength: 0)
        let archivedStructLength = sizeof(ArchivedPacket) //lenght of the struct

        //Get the data tha will form our archived Packet
        let archivedData = data.subdataWithRange(NSMakeRange(0, archivedStructLength))
        //save the data taht form the archivedPacket inside the archivedPacket
        archivedData.getBytes(&archivedPacket, length: archivedStructLength)
        //get the range of data that contains the name
        let nameRange = NSMakeRange(archivedStructLength, Int(archivedPacket.nameLength))
        //get the range of the data that contains the data
        let dataRange = NSMakeRange(archivedStructLength + Int(archivedPacket.nameLength), Int(archivedPacket.dataLength))
        //get the data that rappresent the name
        let nameData = data.subdataWithRange(nameRange)
        //Get the name frome the data
        let name = NSString(data: nameData, encoding: NSUTF8StringEncoding) as! String
        // Geth the data
        let theData = data.subdataWithRange(dataRange)

        //Create the struct
        let messageRndm = MessageRandomWords(data: theData, name: name)
        return messageRndm
    }

}

If you create the struct as showed, you can send your array of string by encode it as NSData and then decode it when received.

You can find the full working example on GitHub

If you have some better solutions please leave some feedback

Community
  • 1
  • 1
Max_Power89
  • 1,710
  • 1
  • 21
  • 38