【问题标题】:How to load and save data? - Swift如何加载和保存数据? - 斯威夫特
【发布时间】:2021-07-05 17:44:10
【问题描述】:

我正在关注一个标记收藏夹的教程,他们忽略了如何加载和保存数据,所以如果你们能提供帮助,那就太好了。

这是我的代码:

class Favorites: ObservableObject {
    
    private var task: Set<Int>
    
    private let saveKey = "Favorites"
    
    init() {
        // load Saved data
        
        self.task = []
    }
    
    func contains(_ sclocations: SClocation) -> Bool {
        task.contains(sclocations.id)
    }
    
    func add(_ sclocations: SClocation) -> Bool {
        objectWillChange.send()
        task.insert(sclocations.id)
        save()
    }
    
    func remove(_ sclocations: SClocation) -> Bool {
        objectWillChange.send()
        task.remove(sclocations.id)
        save()
    }
    
    func save() {
        // Write out Data
    }
}

这是不断崩溃的部分:

Button(favorites.contains(sclocations) ? "Remove from Favorites" : "Add to Favorites") {
                        if self.favorites.contains(self.sclocations) {
                            self.favorites.remove(self.sclocations)
                        } else {
                            self.favorites.add(self.sclocations)
                        }
                    }

【问题讨论】:

    标签: arrays json swift swiftui


    【解决方案1】:

    UserDefaults 是用于此目的的常用工具。它将持久数据存储在键值存储中。

    你可以这样使用它:

    class Favorites: ObservableObject {
        
        private var task: Set<Int>
        
        private let saveKey = "Favorites"
        
        init() {
            self.task = Set((UserDefaults.standard.array(forKey: saveKey) as? [Int]) ?? [])
        }
        
        func contains(_ sclocations: SClocation) -> Bool {
            task.contains(sclocations.id)
        }
        
        func add(_ sclocations: SClocation) -> Bool {
            objectWillChange.send()
            task.insert(sclocations.id)
            save()
            return true
        }
        
        func remove(_ sclocations: SClocation) -> Bool {
            objectWillChange.send()
            task.remove(sclocations.id)
            save()
            return true
        }
        
        func save() {
            // Write out Data
            UserDefaults.standard.setValue(Array(task), forKey: saveKey)
        }
    }
    

    我也可能会稍微重构您的代码。在@Published 变量上使用didSet 似乎更干净。此外,您的add/remove 函数有不必要的Bool 返回。

    class Favorites: ObservableObject {
        @Published var task: Set<Int> {
            didSet {
                save()
            }
        }
        
        private let saveKey = "Favorites"
        
        init() {
            self.task = Set((UserDefaults.standard.array(forKey: saveKey) as? [Int]) ?? [])
        }
        
        func contains(_ sclocations: SClocation) -> Bool {
            task.contains(sclocations.id)
        }
        
        func add(_ location: SClocation) {
            task.insert(location.id)
        }
        
        func remove(_ location: SClocation) {
            task.remove(location.id)
        }
        
        func save() {
            UserDefaults.standard.setValue(Array(task), forKey: saveKey)
        }
    }
    

    您甚至可以去掉上面的add/remove 函数,直接在task@Published 属性上调用insertremove


    除了使用 UserDefaults 之外的另一个选择是查看 Core Data (https://developer.apple.com/documentation/coredata)——有很多关于这方面的教程——不过,对于如何集成它,这将是一个更长、更复杂的答案.

    【讨论】:

    • 我在我的代码中不断崩溃的部分的问题中添加了一个部分。你知道如何解决吗? @jnpdx
    • 它说“致命错误:未找到收藏夹类型的 ObservableObject。收藏夹的 View.environmentObject(_:) 作为此视图的祖先可能会丢失。” @jnpdx
    • 这个错误告诉你到底是什么问题。您已在某处将favorites 定义为@EnvironmentObject var favorites: Favorites,但您需要在某处的父视图中通过.environmentObject 传入Favorites 的实例。例如,请参阅此链接:stackoverflow.com/a/65754383/560942
    猜你喜欢
    • 2016-09-29
    • 2017-07-22
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2018-07-27
    • 2015-12-31
    相关资源
    最近更新 更多