我有一个名为’News’的自定义结构,我想将其附加到NSUserDefault的数组中.但它显示错误“类型’新闻’不符合协议’AnyObject’”.
我不想将’News’结构更改为类,因为它已经被用于其他代码.无论如何我可以将NSUserDefaults.standardUserDefaults().arrayForKey(“savedNewsArray”)类型更改为[新闻]?
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()
这是’新闻’结构.
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只能保存一小组类型:NSData,NSString,NSNumber,NSDate,仅包含这些类型的NSArray,或仅包含这些类型的NSDictionary.因此,最好的办法是使用NSKeyedUnarchiver对结构进行编码,这需要一个符合NSCoding的值.你可以让你的类型符合这一点,但我认为从你的用户隐藏它并且只是为内部表示创建一个私有类更清晰,如下所示:
原文链接:https://www.f2er.com/swift/320054.htmlstruct Foo { var a : String var b : String? } extension Foo { init?(data: NSData) { if let coding = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? Encoding { a = coding.a as String b = coding.b as String? } else { return nil } } func encode() -> NSData { return NSKeyedArchiver.archivedDataWithRootObject(Encoding(self)) } private class Encoding: NSObject,NSCoding { let a : NSString let b : NSString? init(_ foo: Foo) { a = foo.a b = foo.b } @objc required init?(coder aDecoder: NSCoder) { if let a = aDecoder.decodeObjectForKey("a") as? NSString { self.a = 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") } } }
然后,为了保存您的阵列,您只需将.encode映射到您的阵列:
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")
为了得到它,你可以简单地将NSData传递给init:
let dataArray = NSUserDefaults.standardUserDefaults().objectForKey("my-key") as! [NSData] let savedFoo = dataArray.map { Foo(data: $0)! }