如何保存结构的顺序?

时间:2017-12-09 11:09:46

标签: ios swift struct save nsuserdefaults

我创建了一个应用程序,它从数组中随机显示不同的字符串。为了确保没有数组重复,我创建了一个结构,它只显示尚未显示的字符串。

这很好用,但我的问题是,只要切换场景,结构就会重置,尽管我试图将其保存为用户默认值。 当我尝试应用UserDefaults时,有人知道我在哪里犯了错误吗?

这是包含保存方法的结构:

 struct RandomItems: Codable
{
    var items : [String]
    var seen  = 0

    init(items:[String], seen: Int)
    {
        self.items = items
        self.seen = seen
    }
    init(_ items:[String])
    { self.init(items: items, seen: 0) }

    mutating func next() -> String
    {
        let index = Int(arc4random_uniform(UInt32(items.count - seen)))
        let item  = items.remove(at:index)
        items.append(item)
        seen = (seen + 1) % items.count
        return item
    }
    func toPropertyList() -> [String: Any] {
        return [
            "items": items,
            "seen": seen]
       }
      }
override func viewDidLoad() {
    let defaults = UserDefaults.standard
    if let quotes = defaults.codable(RandomItems.self, forKey: "quotes") as? RandomItems {
        self.quotes = quotes
    }
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector:Selector(("saveData:")), name: Notification.Name.UIApplicationWillTerminate, object:nil)
}
func storeQuotes() {
    // Code to save struct
    let defaults = UserDefaults.standard
    if let quotes = quotes {
        defaults.set(codable: quotes, forKey: "quotes")
    }
}
override func viewDidAppear(_ animated: Bool) {
    // Code to load the struct again after the view appears.

}

override func viewWillDisappear(_ animated: Bool) {

     storeQuotes()
}
func saveData(notification: Notification) {
    // Save your data here when app is closed
    print("Saving data...")
    storeQuotes()
  }

 }

extension UserDefaults {

func set<T: Encodable>(codable: T, forKey key: String) {
    let encoder = JSONEncoder()
    do {
        let data = try encoder.encode(codable)
        let jsonString = String(data: data, encoding: .utf8)!
        print("Saving \"\(key)\": \(jsonString)")
        self.set(jsonString, forKey: key)
    } catch {
        print("Saving \"\(key)\" failed: \(error)")
    }
  }
 func codable<T: Decodable>(_ codable: T.Type, forKey key: String) -> T? {
    guard let jsonString = self.string(forKey: key) else { return nil }
    guard let data = jsonString.data(using: .utf8) else { return nil }
    let decoder = JSONDecoder()
    print("Loading \"\(key)\": \(jsonString)")
    return try? decoder.decode(codable, from: data)
}

1 个答案:

答案 0 :(得分:0)

如果您已在UserDefaults中存储了值,则可以签入viewDidLoad,并且可以在viewDidAppear中删除您的代码:

override func viewDidLoad() {
    let defaults = UserDefaults.standard
    if let quotes = defaults.codable(RandomItems.self, forKey: "quotes") as? RandomItems { 
        self.quotes = quotes 
    } 
}

修改

如果您想在应用移动到后台时存储报价:

在viewWillAppear中添加通知观察者:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(saveData), name: Notification.Name.UIApplicationDidEnterBackground, object:nil)
}

func storeQuotes() {
    // Code to save struct 
    let defaults = UserDefaults.standard
    if let quotes = quotes {
        defaults.set(codable: quotes, forKey: "quotes")
    }
}

override func viewWillDisappear(_ animated: Bool) {
    // Code to save struct before the view disappears.
    storeQuotes()
}

func saveData() {
    // Save your data here when app is closed 
    print("Saving data...")
    storeQuotes()
}