将 DateComponents 数组设置为 UserDefaults 不起作用
Setting DateComponents array to UserDefaults not working
我正在制作一个单视图应用程序,它管理一个人处理的所有任务。我有两个数组:一个存储所有任务名称,一个显示任务的完成时间。我将这两个分配给 UserDefaults:
var tasks = [String]()
var finishingDates = [DateComponents]()
let defaults = UserDefaults()
class ViewController: UIViewController {
func setDefaults() {
defaults.set(tasks, forKey: "tasks")
defaults.set(finishingDates, forKey: "finishingDates")
}
override func viewDidLoad() {
super.viewDidLoad()
tasks = defaults.stringArray(forKey: "tasks") ?? [String]()
finishingDates = defaults.array(forKey: "finishingDates") as? [DateComponents] ?? [DateComponents]()
}
}
然后我测试以确保阵列正常工作:
tasks = ["task"]
finishingDates = [DateComponents(calendar: calendar, year: 1910, month: 10, day: 1)]
setDefaults()
但是,当我 运行 它时,应用程序崩溃了。在应用程序委托中,存在 SIGABRT 错误。
我添加了一个异常断点,它在这一行被调用:
defaults.set(finishingDates, forKey: "finishingDates")
它只在这一行被调用,而不是在设置字符串数组的那一行被调用。除此之外,数组是相同的。我该如何解决?
您不能将 DateComponents 对象数组直接保存到 UserDefaults,但可以保存其数据。 DateComponents 符合 Codable 协议,因此您只需要使用 JSONEncoder/JSONDecoder encode/decode 数组并保存结果数据。顺便说一句,我建议将其写入 JSON 文本文件,而不是使用 UserDefaults:
保存它
游乐场测试:
var finishingDates: [DateComponents] = []
finishingDates.append(.init(calendar: .current, year: 2019, month: 7, day: 13))
finishingDates.first!.month!
do {
let finishingDatesData = try JSONEncoder().encode(finishingDates)
print(String(data: finishingDatesData, encoding: .utf8) ?? "")
UserDefaults.standard.set(finishingDatesData, forKey: "finishingDates")
print("finishingDates saved to userdefaults")
if let data = UserDefaults.standard.data(forKey: "finishingDates") {
let loadedDateComponents = try JSONDecoder().decode([DateComponents].self, from: data)
print(loadedDateComponents) // "[calendar: gregorian (fixed) year: 2019 month: 7 day: 13 isLeapMonth: false ]\n"
}
} catch {
print(error)
}
这将打印:
"[{"day":13,"year":2019,"calendar":{"locale":{"identifier":"en_US"},"timeZone":{"identifier":"America\/Sao_Paulo"},"identifier":"gregorian","minimumDaysInFirstWeek":1,"firstWeekday":1},"month":7}]\n"
和
"[calendar: gregorian (fixed) year: 2019 month: 7 day: 13 isLeapMonth: false ]\n"
我正在制作一个单视图应用程序,它管理一个人处理的所有任务。我有两个数组:一个存储所有任务名称,一个显示任务的完成时间。我将这两个分配给 UserDefaults:
var tasks = [String]()
var finishingDates = [DateComponents]()
let defaults = UserDefaults()
class ViewController: UIViewController {
func setDefaults() {
defaults.set(tasks, forKey: "tasks")
defaults.set(finishingDates, forKey: "finishingDates")
}
override func viewDidLoad() {
super.viewDidLoad()
tasks = defaults.stringArray(forKey: "tasks") ?? [String]()
finishingDates = defaults.array(forKey: "finishingDates") as? [DateComponents] ?? [DateComponents]()
}
}
然后我测试以确保阵列正常工作:
tasks = ["task"]
finishingDates = [DateComponents(calendar: calendar, year: 1910, month: 10, day: 1)]
setDefaults()
但是,当我 运行 它时,应用程序崩溃了。在应用程序委托中,存在 SIGABRT 错误。
我添加了一个异常断点,它在这一行被调用:
defaults.set(finishingDates, forKey: "finishingDates")
它只在这一行被调用,而不是在设置字符串数组的那一行被调用。除此之外,数组是相同的。我该如何解决?
您不能将 DateComponents 对象数组直接保存到 UserDefaults,但可以保存其数据。 DateComponents 符合 Codable 协议,因此您只需要使用 JSONEncoder/JSONDecoder encode/decode 数组并保存结果数据。顺便说一句,我建议将其写入 JSON 文本文件,而不是使用 UserDefaults:
保存它游乐场测试:
var finishingDates: [DateComponents] = []
finishingDates.append(.init(calendar: .current, year: 2019, month: 7, day: 13))
finishingDates.first!.month!
do {
let finishingDatesData = try JSONEncoder().encode(finishingDates)
print(String(data: finishingDatesData, encoding: .utf8) ?? "")
UserDefaults.standard.set(finishingDatesData, forKey: "finishingDates")
print("finishingDates saved to userdefaults")
if let data = UserDefaults.standard.data(forKey: "finishingDates") {
let loadedDateComponents = try JSONDecoder().decode([DateComponents].self, from: data)
print(loadedDateComponents) // "[calendar: gregorian (fixed) year: 2019 month: 7 day: 13 isLeapMonth: false ]\n"
}
} catch {
print(error)
}
这将打印:
"[{"day":13,"year":2019,"calendar":{"locale":{"identifier":"en_US"},"timeZone":{"identifier":"America\/Sao_Paulo"},"identifier":"gregorian","minimumDaysInFirstWeek":1,"firstWeekday":1},"month":7}]\n"
和
"[calendar: gregorian (fixed) year: 2019 month: 7 day: 13 isLeapMonth: false ]\n"