我是编程新手。我已经创建了一个Codable
类型,但我不知道我必须在函数viewWillDisappear
中放置什么,其中结构应该保存到UserDefaults
以及我必须放在函数viewDidAppear
,其中应该再次显示保存的结构。
到目前为止,这是我的代码:
import UIKit
class QuotesViewController: UIViewController {
var randomItems: RandomItems?
var quotes: RandomItems! = RandomItems([
"Andre",
"James",
"Max",
"Stephen",
"Sarah",
"Jeff",
"Paul",
"Mary",
])
}
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
defaults.set(codable: quotes, forKey: "quotes")
}
override func viewDidAppear(_ animated: Bool) {
// Code to load the struct again after the view appears.
let defaults = UserDefaults.standard
quotes = defaults.codable(RandomItems.self, forKey: "quotes") ??
RandomItems([])
}
override func viewWillDisappear(_ animated: Bool) {
// Code to save struct before the view disappears.
let defaults = UserDefaults.standard
if let quotes = quotes {
defaults.set(codable: quotes, forKey: "quotes")
}
}
}
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)
}
}
答案 0 :(得分:0)
在ViewController中创建一个属性/变量,以保存RandomItems的值
var randomItems: RandomItems?
在viewWillDisappear方法中,使用您的密钥将数据保存到UserDefaults中。
if let propertyList = self.randomItems?.toPropertyList() {
UserDefaults.standard.setValue(propertyList, forKey: "MyItems")
}
在viewWillAppear方法中,从UserDefaults获取数据并将其分配给您的变量
if let propertyList = UserDefaults.standard.dictionary(forKey: "MyItems") {
self.randomItems = RandomItems(propertyList: propertyList)
}
答案 1 :(得分:0)
设计此方法的一个好方法是使用一对辅助方法扩展 UserDefaults
:
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)
}
}
然后在QuotesViewController
:
class QuotesViewController: UIViewController {
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)
}
}
var quotes: RandomItems! = RandomItems([
"James",
"John",
"William",
])
override func viewDidAppear(_ animated: Bool) {
// Code to load the struct again after the view appears.
let defaults = UserDefaults.standard
quotes = defaults.codable(RandomItems.self, forKey: "quotes")
}
override func viewWillDisappear(_ animated: Bool) {
// Code to save struct before the view disappears.
let defaults = UserDefaults.standard
if let quotes = quotes {
defaults.set(codable: quotes, forKey: "quotes")
}
}
}
输入(并退出)上述视图控制器会打印:
保存&#34;报价&#34;:{&#34;项目&#34;:[&#34; James&#34;,&#34; John&#34;,&#34; William&#34; ]&#34;看出&#34;:0}
正在加载&#34;报价&#34;:{&#34;项目&#34;:[&#34; James&#34;,&#34; John&#34;,&#34; William&#34;],& #34;看出&#34;:0}
<强>更新即可。对于它的价值,下面是我用来在Xcode 9游乐场测试的完整的代码:
import Foundation
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)
}
}
class UIViewController: NSObject {
func viewDidAppear(_ animated: Bool) { }
func viewWillDisappear(_ animated: Bool) { }
}
class QuotesViewController: UIViewController {
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)
}
}
var quotes: RandomItems! = RandomItems([
"James",
"John",
"William",
"Mary",
"Sarah",
"Michael",
"Steve",
"Lisa",
"Jeff",
"Chris",
])
override func viewDidAppear(_ animated: Bool) {
// Code to load the struct again after the view appears.
let defaults = UserDefaults.standard
quotes = defaults.codable(RandomItems.self, forKey: "quotes")
}
override func viewWillDisappear(_ animated: Bool) {
// Code to save struct before the view disappears.
let defaults = UserDefaults.standard
if let quotes = quotes {
defaults.set(codable: quotes, forKey: "quotes")
}
}
}
let vc = QuotesViewController()
vc.viewWillDisappear(false)
vc.quotes = nil
vc.viewDidAppear(true)
print(vc.quotes)