我有一个名为ArticleArchive的快速类,如下所示
import Foundation
class ArticleArchive: NSObject, NSCoding {
var entries: Dictionary<String, Dictionary<String, String>>?
var userDefaultsKey = "savedArticles"
override init() {
self.entries = Dictionary<String, Dictionary<String, String>>()
}
init(articles: Dictionary<String, Dictionary<String, String>>) {
self.entries = articles
}
required init(coder aDecoder: NSCoder) {
self.entries = aDecoder.decodeObjectForKey(userDefaultsKey) as? Dictionary
}
func encodeWithCoder(aCoder: NSCoder) {
if let articles = self.entries {
aCoder.encodeObject(articles, forKey: userDefaultsKey)
}
}
func populateArticles(articles: Dictionary<String, Dictionary<String, String>>) {
self.entries = articles
}
func save() {
let data = NSKeyedArchiver.archivedDataWithRootObject(self)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: userDefaultsKey)
}
func clear() {
NSUserDefaults.standardUserDefaults().removeObjectForKey(userDefaultsKey)
}
class func loadSaved() -> ArticleArchive? {
if let data = NSUserDefaults.standardUserDefaults().objectForKey("savedArticles") as? NSData {
return NSKeyedUnarchiver.unarchiveObjectWithData(data) as? ArticleArchive
}
return nil
}
}
在viewController中,我在类的顶部有以下类型为ArticleArchive
的var
var savedArticles : ArticleArchive? = nil
在viewDidLoad
中,我执行以下操作来初始化变量
if let savedArticles:ArticleArchive = ArticleArchive.loadSaved() {
self.savedArticles = savedArticles
} else {
self.savedArticles = ArticleArchive()
}
我正在尝试将Dictionary<String, String>
插入到savedArticles
变量中,但它不起作用。
let currentDictionary = filtered[indexPath.row] as Dictionary<String, String>
self.savedArticles?.entries[currentDictionary["link"]] = currentDictionary
我收到一条错误消息,指出&#34;无法找到&#39;下标&#39;接受提供的参数&#34;
我在圈子里尝试不同的东西,但没有运气,也许有人可以帮助我。如何将currentDictionary(Dictionary<String, String>
)插入savedArticles
?
答案 0 :(得分:3)
如果字典entries
不可选,则插入有效
有充分的理由使用非可选类型。
假设当对象ArticleArchive
存在时,还存在默认为空的entries
字典。
encodeWithCoder
和init(coder)
方法也是安全的,因为它确保非可选的entries
字典即使在空的情况下仍然保存,所以它永远不会是零。
这是代码
修改:我添加了一个类型别名ArticleDictionary
以提高可读性
class ArticleArchive: NSObject, NSCoding {
typealias ArticleDictionary = Dictionary<String, Dictionary<String, String>>
var entries: ArticleDictionary
var userDefaultsKey = "savedArticles"
override init() {
self.entries = ArticleDictionary()
}
init(articles: ArticleDictionary) {
self.entries = articles
}
required init(coder aDecoder: NSCoder) {
self.entries = aDecoder.decodeObjectForKey(userDefaultsKey) as! ArticleDictionary
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.entries, forKey: userDefaultsKey)
}
func populateArticles(articles: ArticleDictionary) {
self.entries = articles
}
func save() {
let data = NSKeyedArchiver.archivedDataWithRootObject(self)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: userDefaultsKey)
}
func clear() {
NSUserDefaults.standardUserDefaults().removeObjectForKey(userDefaultsKey)
}
class func loadSaved() -> ArticleArchive? {
if let data = NSUserDefaults.standardUserDefaults().objectForKey("savedArticles") as? NSData {
return NSKeyedUnarchiver.unarchiveObjectWithData(data) as? ArticleArchive
}
return nil
}
}
由于link
键可能不存在,因此必须解开该值。
savedArticles.entries[currentDictionary["link"]!] = currentDictionary
答案 1 :(得分:1)
我修改了你的类以使用这个方法:
func addEntry(key:String, dict:Dictionary<String,String>){
self.entries![key] = dict;
}
然后你可以这样做:
self.savedArticles?.addEntry(currentDictionary["link"]!, dict: currentDictionary)
似乎工作。
编辑:如果由于某种原因entries
必须保持可选,那么这可以防止运行时崩溃(有点hacky但有效)
func addEntry(key:String, dict:Dictionary<String,String>){
if let e = self.entries{
self.entries![key] = dict;
}else{
print("avoided runtime crash!")
}
}