如何保存结构的顺序?
How to save the order of a struct?
我创建了一个随机显示数组中不同字符串的应用程序。为了确保没有数组被重复,我创建了一个结构,它只显示尚未显示的字符串。
效果很好,但我的问题是,一旦我切换场景,结构就会重置,尽管我试图将它保存为用户默认值。
有人知道我在尝试应用 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)
}
如果您已经在 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()
}
我创建了一个随机显示数组中不同字符串的应用程序。为了确保没有数组被重复,我创建了一个结构,它只显示尚未显示的字符串。
效果很好,但我的问题是,一旦我切换场景,结构就会重置,尽管我试图将它保存为用户默认值。 有人知道我在尝试应用 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)
}
如果您已经在 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()
}