How can I get an NSCoder to encode/decode a Swift array of structs? -


i have object must conform nscoding , holds array of uint64 values. how can encode/decode nscoder @ all? bonus question: how can encode compactly? (it has go saved game center state data, size limited.)

ideally, want write int size n of array, , write n times 64 bits of uint64, , read similarly. can this?

coder.encodeobject(values, forkey: "v") doesn't work.

class myobject: nscoding {      private var values: [uint64]      // …      // mark: - nscoding      required init(coder decoder: nscoder) {         // ???     }      func encodewithcoder(coder: nscoder) {         // ???     }   } 

here possible solution encodes uint64 array array of bytes. inspired answers how serialize c array nscoding?.

class myobject: nsobject, nscoding {      var values: [uint64] = []      init(values : [uint64]) {         self.values = values     }      // mark: - nscoding     required init(coder decoder: nscoder) {         super.init()         var count = 0         // decodebytesforkey() returns unsafepointer<uint8>, pointing immutable data.         let ptr = decoder.decodebytesforkey("values", returnedlength: &count)         // if convert buffer pointer of appropriate type , count ...         let buf = unsafebufferpointer<uint64>(start: unsafepointer(ptr), count: count/sizeof(uint64))         // ... array creation becomes easy.         values = array(buf)     }      func encodewithcoder(coder: nscoder) {         // encodes both number of bytes , data itself.         coder.encodebytes(unsafepointer(values), length: values.count * sizeof(uint64), forkey: "values")     } } 

test:

let obj = myobject(values: [1, 2, 3, uint64.max]) let data = nskeyedarchiver.archiveddatawithrootobject(obj)  let dec = nskeyedunarchiver.unarchiveobjectwithdata(data) as! myobject print(dec.values) // [1, 2, 3, 18446744073709551615] 

update swift 3 (xcode 8):

class myobject: nsobject, nscoding {      var values: [uint64] = []      init(values : [uint64]) {         self.values = values     }      // mark: - nscoding     required init(coder decoder: nscoder) {         super.init()         var count = 0         // decodebytesforkey() returns unsafepointer<uint8>?, pointing immutable data.         if let ptr = decoder.decodebytes(forkey: "values", returnedlength: &count) {             // if convert buffer pointer of appropriate type , count ...             let numvalues = count / memorylayout<uint64>.stride             ptr.withmemoryrebound(to: uint64.self, capacity: numvalues) {                 let buf = unsafebufferpointer<uint64>(start: unsafepointer($0), count: numvalues)                 // ... array creation becomes easy.                 values = array(buf)             }         }     }      public func encode(with coder: nscoder) {         // encodes both number of bytes , data itself.         let numbytes = values.count * memorylayout<uint64>.stride         values.withunsafebufferpointer {             $0.baseaddress!.withmemoryrebound(to: uint8.self, capacity: numbytes) {                 coder.encodebytes($0, length: numbytes, forkey: "values")             }         }     } }   let obj = myobject(values: [1, 2, 3, uint64.max]) let data = nskeyedarchiver.archiveddata(withrootobject: obj)  let dec = nskeyedunarchiver.unarchiveobject(with: data) as! myobject print(dec.values) // [1, 2, 3, 18446744073709551615] 

Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -