How to save an array of custom struct to NSUserDefault with swift? -
i have custom struct called 'news' want append array nsuserdefault. it's showing error "type 'news' not conform protocol 'anyobject'".
i don't want change 'news' struct class since it's being used other code already. there anyway can change nsuserdefaults.standarduserdefaults().arrayforkey("savednewsarray") type [news]?
var savednews = nsuserdefaults.standarduserdefaults().arrayforkey("savednewsarray") var addsavednews = savednews as? [news] addsavednews.append(news(id: "00", title: newstitle, source: source, imageurl: imageurl, url: url)) nsuserdefaults.standarduserdefaults().setobject(addsavednews, forkey: "savednewsarray") nsuserdefaults.standarduserdefaults().synchronize()
here 'news' struct.
public struct news { public var id: string public var title: string public var source: string? public var imageurl: string? public var date: nsdate? public var url: string init(id: string, title: string, source: string, imageurl: string, url: string) { self.id = id self.title = title self.source = source self.imageurl = imageurl self.url = url } }
nsuserdefaults can save small set of types: nsdata
, nsstring
, nsnumber
, nsdate
, nsarray
containing these types, or nsdictionary
containing these types. best bet encode struct using nskeyedunarchiver, required value conforms nscoding. make type conform this, think it's cleaner hide users , have private class internal representation, this:
struct foo { var : string var b : string? } extension foo { init?(data: nsdata) { if let coding = nskeyedunarchiver.unarchiveobjectwithdata(data) as? encoding { = coding.a string b = coding.b string? } else { return nil } } func encode() -> nsdata { return nskeyedarchiver.archiveddatawithrootobject(encoding(self)) } private class encoding: nsobject, nscoding { let : nsstring let b : nsstring? init(_ foo: foo) { = foo.a b = foo.b } @objc required init?(coder adecoder: nscoder) { if let = adecoder.decodeobjectforkey("a") as? nsstring { self.a = } else { return nil } b = adecoder.decodeobjectforkey("b") as? nsstring } @objc func encodewithcoder(acoder: nscoder) { acoder.encodeobject(a, forkey: "a") acoder.encodeobject(b, forkey: "b") } } }
then save array can map .encode
on array:
let fooarray = [ foo(a: "a", b: "b"), foo(a: "c", b: nil) ] let encoded = fooarray.map { $0.encode() } nsuserdefaults.standarduserdefaults().setobject(encoded, forkey: "my-key")
and can pass nsdata
init:
let dataarray = nsuserdefaults.standarduserdefaults().objectforkey("my-key") as! [nsdata] let savedfoo = dataarray.map { foo(data: $0)! }
Comments
Post a Comment