userdefaults 使用问题 swift 3

Posted

技术标签:

【中文标题】userdefaults 使用问题 swift 3【英文标题】:Issues with userdefaults usage swift 3 【发布时间】:2017-07-08 08:15:01 【问题描述】:

我刚开始学习 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)
        
    

谁能帮助我或至少指出我必须做什么?谢谢!

【问题讨论】:

简单的Google search 怎么样? 正如我告诉你的那样。我不明白如何处理代码。欢迎有用的cmets! :-) ... 还是 *** search ?顺便问一下,readFrom- / writeToPersistence 函数有什么作用? 您必须更具体。从您的项目中提取所有与持久性(读取和写入)相关的代码,详细解释您正在尝试做什么(时钟是什么)以及发生了什么。 “不起作用”永远不会得到你的回答。 再次使用 tableview 实现...这里唯一重要的代码是 ToDoItemwriteToPersistencereadFromPersistence(可能还有 configureCell(todo:))的实现,这是您的代码坚持不显示... 【参考方案1】:

您正在使用NSKeyedArchiverNSKeyedUnarchiver,这是与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")
    

【讨论】:

以上是关于userdefaults 使用问题 swift 3的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 userDefaults 保存打印数组(swift 3)

如何使用 UserDefaults swift 3 提取 JobSeekerID

如何使用 UserDefaults.standard 在 Swift 3.0 中保持会话?

在 Swift 3 中删除 UserDefaults 的单个键值

Swift 3 UserDefaults 设置 NSMutableArray

在 Swift 3 中设置 UserDefaults 的问题