我刚刚开始学习Swift,所以这个问题的级别可能对你来说足够明显,但是,我根本无法理解该做什么。
我"创建"一个简单的应用程序,允许您添加当天的日志。每个单元格存储您添加的时间,根据时间更改的自定义图标,以及日志文本本身(简单文本)。
一切正常。但是,因为我不知道" Userdefaults"东西,每当我杀死应用程序时,时钟都会重置。
我阅读了很多关于Userdefaults的文章,但我不知道该怎样做才能保存我的数据,即使我杀了应用程序。
这是我尝试做的事情:
class ToDoItem: NSObject, NSCoding {
var title: String
var date: String
var type: String!
public init(title: String, date: String, type: String) {
self.title = title
self.date = date
self.type = type
}
required init?(coder aDecoder: NSCoder)
{
// Try to unserialize the "title" variable
if let title = aDecoder.decodeObject(forKey: "title") as? String
{
self.title = title
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .none
dateFormatter.timeStyle = .short
self.date = dateFormatter.string(from: Date())
let hour = NSCalendar.current.component(.hour, from: Date())
var tempType = ""
switch hour {
case 5..<9: tempType = "morning_1"
case 6..<12: tempType = "morning_2"
case 12: tempType = "noon_1"
case 13..<16: tempType = "afternoon_1"
case 16..<20: tempType = "dusk_1"
case 20..<23: tempType = "evening_1"
case 23..<00: tempType = "midnight_1"
default: tempType = "morning_1"
}
self.type = tempType
}
else
{
// There were no objects encoded with the key "title",
// so that's an error.
return nil
}
let userDefaults = UserDefaults.standard
userDefaults.set(true, forKey: "title")
}
func encode(with aCoder: NSCoder)
{
// Store the objects into the coder object
aCoder.encode(self.title, forKey: "title")
let defaults = UserDefaults.standard
defaults.set(false, forKey: "title")
}
}
extension Collection where Iterator.Element == ToDoItem
{
// Builds the persistence URL. This is a location inside
// the "Application Support" directory for the App.
private static func persistencePath() -> URL?
{
let url = try? FileManager.default.url(
for: .applicationSupportDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: true)
return url?.appendingPathComponent("todoitems.bin")
}
// Write the array to persistence
func writeToPersistence() throws
{
if let url = Self.persistencePath(), let array = self as? NSArray
{
let data = NSKeyedArchiver.archivedData(withRootObject: array)
try data.write(to: url)
}
else
{
throw NSError(domain: "com.example.MyToDo", code: 10, userInfo: nil)
}
}
// Read the array from persistence
static func readFromPersistence() throws -> [ToDoItem]
{
if let url = persistencePath(), let data = (try Data(contentsOf: url) as Data?)
{
if let array = NSKeyedUnarchiver.unarchiveObject(with: data) as? [ToDoItem]
{
return array
}
else
{
throw NSError(domain: "com.example.MyToDo", code: 11, userInfo: nil)
}
}
else
{
throw NSError(domain: "com.example.MyToDo", code: 12, userInfo: nil)
}
}
}
任何人都可以帮助我或者至少指出我必须做的事情吗?谢谢!
答案 0 :(得分:2)
您使用的是NSKeyedArchiver
和NSKeyedUnarchiver
,这是一种与UserDefaults
不同的机制。两者都是完全有效的,但你必须选择一个,它们不能一起工作。
您可以在此归档和取消归档ToDoItem
数组。为了实现这一点,ToDoItem
需要是可存档的,这意味着它必须实现NSCoding
协议,即:
public protocol NSCoding {
public func encode(with aCoder: NSCoder)
public init?(coder aDecoder: NSCoder) // NS_DESIGNATED_INITIALIZER
}
您要保存的所有属性必须添加到NSCoder
对象中/从中提取。这是一个例子:
class ToDoItem: NSObject, NSCoding
{
var title: String
var date: Date
required init?(coder aDecoder: NSCoder)
{
guard let title = aDecoder.decodeObject(forKey: "title") as? String else {
return nil
}
guard let date = aDecoder.decodeObject(forKey: "date") as? Date else {
return nil
}
self.title = title
self.date = date
}
func encode(with aCoder: NSCoder)
{
aCoder.encode(self.title, forKey: "title")
aCoder.encode(self.date, forKey: "date")
}
}