SwiftUI 用户数据持久化存储

SwiftUI 用户数据持久化存储

分类说明

持久化可以有多种形式,如 UserDefaults(用户默认),使用 FileManager(文件管理器)本地储存,以及 CoreData(核心数据)。

UserDefaults

如果想要让用户可以持久化他们的偏好设置,如首选的时间格式,UserDefaults(用户默认)是个很好的办法。UserDefaults 十分适合用于储存和管理较小的数据块。你可以直接使用 AppStorage (App 储存空间)属性包装器储存 UserDefaults。例如,你可以通过这个代码片段储存名称值,UserDefaults 键为 name(名称):

@AppStorage ("Zf7") var name: String = "Blu"
图片[1]-SwiftUI 用户数据持久化存储-梦闯の天下
来自 Playground

FileManager

在 SwiftUI 中,开发者可以将易于程序运行的 Event 数组转化为易于高效存储的 JSON 进行保存。

getEventsFileURL(获取事件文件 URL)方法使用 FileManager 来获取数据储存的位置。这种情况下,你的数据位于“文稿”目录内的 App 容器中。只有你的 App 可以读取和写入这个位置。

    private static func getEventsFileURL() throws -> URL {
        FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            .appendingPathComponent("events.data")
    }

如果要使用储存的数据,你将需要从“文稿”目录中载入它。

数据读取

通过调用 EventData.getEventsFileURL() 来获取数据文件的位置。这个操作会在“文稿”目录中查找名为 events.data 的文件。由于方法调用可能会抛出错误,你需要将它放在 do-catch(执行-捕获)语句中。do 子句中抛出的任何错误都可以在 catch 子句中处理:

func load() {
        do {
            let fileURL = try EventData.getEventsFileURL()  //从 URL 中获取文件位置,读取 App 在文稿目录中的 events.data。
            let data = try Data(contentsOf: fileURL)  //将文件内容作为 data(数据)读入内存。
            events = try JSONDecoder().decode([Event].self, from: data)  //JSONDecoder(JSON 解码器)将数据解码为 event 数组,以可以在代码中使用(呀呼!)。
            print("Events loaded: \(events.count)")
        } catch {
            print("Failed to load from file. Backup data used")  //读取失败则反馈 catch 中的预填充事件(必要)。
        }
    }

数据存储

相同的,也可以用类似办法将数组中的数据存储到本地文稿中:

func save() {
        do {
            let fileURL = try EventData.getEventsFileURL()  //获取文件位置。
            let data = try JSONEncoder().encode(events)  //将数组中的数据编码为 JSON。
            try data.write(to: fileURL, options: [.atomic, .completeFileProtection]) //使用获取到的文件位置将数据存储到本地(主义 write 可以抛出错误(可能报错),所以需要将关键词 try(尝试)放在它前面调用。
            print("Events saved")
        } catch {
            print("Unable to save")  //如果数据无法载入,可以打印一则报错信息给控制台。
        }
    }

调用和存储数据

如果要在 App 启动时载入数据,你需要检测顶层视图 EventList 在什么时候出现。出现时,调用 load() 方法。方法会载入数据并将它分配给发布属性 eventData.events,从而使用所有之前存储的数据更新你的事件列表。

使用 task(任务)修饰符,来在视图出现前异步调用 load()

import SwiftUI

@main
struct DatePlannerApp: App {
    @StateObject private var eventData = EventData()
    
    var body: some Scene {
        WindowGroup {
            EventList(eventData: eventData)
//                使用 task 修饰符异步调用 load()。
                .task {
                    eventData.load()
                }
        }
    }
}

用户编辑事件时,你会想要存储数据,以便 App 在下次启动时可以载入。使用 .onChange(of:) 修饰符来检测 events 何时发生了更改,然后调用 eventData.save() 来存储更改:

import SwiftUI

@main
struct DatePlannerApp: App {
    @StateObject private var eventData = EventData()
    
    var body: some Scene {
        WindowGroup {
            EventList(eventData: eventData)
//                使用 task 修饰符异步调用 load()。
                .task {
                    eventData.load()
                }

//                调用函数存储数据的修改。
                .onChange(of: eventData.events) { _ in
                    eventData.save()
                }

        }
    }
}
    © 版权声明
    THE END
    分享和支持
    点赞9 分享
    评论 抢沙发
    头像
    留下评论,见证当下。
    提交
    头像

    昵称

    取消
    昵称表情代码快捷回复

      请登录后查看评论内容