How to Covert struct with an Array of string to NSData and vice versa Swift

不羁的心 提交于 2019-12-02 16:29:59

问题


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?


回答1:


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



来源:https://stackoverflow.com/questions/31564314/how-to-covert-struct-with-an-array-of-string-to-nsdata-and-vice-versa-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!