Swiftui中几种常用的数据存储方式@AppStorage/UserDefaults/CoreData/File Storage/Keychain等

news2024/12/30 3:39:57

在 SwiftUI 中,有多种常用的数据存储方式,根据需求的不同,可以选择适合的存储方案。以下是几种常用的数据存储方式: @AppStorage/UserDefaults/CoreData/File Storage/Keychain,分别来看一下他们的使用场景和区别。

1. @AppStorage 和 UserDefaults

@AppStorage 是 SwiftUI 的一个属性包装器,用于简化对 UserDefaults 的访问。适用于存储简单的数据,例如用户设置和偏好。如果@AppStorage和UserDefaults使用的是同一个key存储的数据,那么他们之间的数据是共享的,值会使用同一个。是一种简单的键值对存储,适用于存储小规模的用户设置。

 @AppStorage示例:

import SwiftUI

struct ContentView: View {
    @AppStorage("username") private var username: String = "Guest"
    
    var body: some View {
        VStack {
            TextField("Username", text: $username)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            Text("Hello, \(username)!")
        }
    }
}

UserDefaults示例:

struct AppStorageDemo: View {

  @State var userName: String?

  var body: some View {
    VStack(spacing: 30) {
      if let userName {
        Text(userName)
          .font(.title)
      }

      Button(action: {
        userName = "Daniel"
        // 使用UserDefaults设置值
        UserDefaults.standard.setValue(userName, forKey: "userName")
      }, label: {
        Text("SAVE")
          .foregroundColor(.white)
          .padding()
          .background(Color.red)
          .clipShape(Capsule())
      })
    }
    .onAppear {
      // 当页面出现的时候,加载UserDefaults里面的值
      userName = UserDefaults.standard.string(forKey: "userName")
    }
  }
}

使用效果展示:

2. @State 和 @StateObject

@State 和 @StateObject 用于管理视图内部的状态。虽然它们通常用于临时状态,但也可以用于简单的数据存储,但是App重新启动或者页面关闭后,这些状态可能就恢复初始值了。

import SwiftUI

struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
            Button(action: {
                count += 1
            }) {
                Text("Increment")
            }
        }
    }
}

3. @ObservedObject 和 @EnvironmentObject

@ObservedObject 和 @EnvironmentObject 用于在视图之间共享状态对象。通常配合 ObservableObject 使用,用于管理复杂的状态和数据。但是也是临时在内存中的数据,App重启后数据就销毁了。

示例:

import SwiftUI

class UserData: ObservableObject {
    @Published var username: String = "Guest"
}

struct ContentView: View {
    @StateObject private var userData = UserData()

    var body: some View {
        VStack {
            TextField("Username", text: $userData.username)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            Text("Hello, \(userData.username)!")
        }
        .environmentObject(userData)
    }
}

struct AnotherView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        Text("Welcome, \(userData.username)!")
    }
}

4. Core Data

Core Data 是一个强大的框架,用于管理对象图和持久化存储。适用于需要持久化和查询复杂数据结构的应用。

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        List {
            ForEach(items) { item in
                Text("Item at \(item.timestamp!, formatter: itemFormatter)")
            }
            .onDelete(perform: deleteItems)
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button(action: addItem) {
                    Label("Add Item", systemImage: "plus")
                }
            }
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { items[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

private let itemFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .medium
    return formatter
}()

5. File Storage

文件存储适用于需要存储大量数据或复杂文件(例如 JSON、图片等)的场景。

import SwiftUI

struct ContentView: View {
    @State private var text: String = ""
    
    var body: some View {
        VStack {
            TextField("Enter some text", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            
            Button("Save to file") {
                saveTextToFile(text)
            }
        }
        .padding()
    }
    
    func saveTextToFile(_ text: String) {
        let filename = getDocumentsDirectory().appendingPathComponent("output.txt")

        do {
            try text.write(to: filename, atomically: true, encoding: String.Encoding.utf8)
            print("Saved to \(filename)")
        } catch {
            print("Failed to write to file: \(error.localizedDescription)")
        }
    }

    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
}

6. Keychain

Keychain 适用于存储敏感数据,例如用户凭证和密码。使用 Keychain 存储数据需要导入 Security 框架并编写相应的读写函数。可以使用第三方库(例如 KeychainAccess)简化操作。

总结

在 SwiftUI 中,常用的数据存储方式包括:

@AppStorage 和 UserDefaults:用于简单、轻量级的数据存储。

@State、@StateObject、@ObservedObject 和 @EnvironmentObject:用于视图和状态管理。

Core Data:用于复杂的数据持久化和查询。

文件存储:用于存储大文件或复杂文件。

Keychain:用于存储敏感数据。

根据应用的需求选择合适的数据存储方案,有助于提升应用的性能和数据管理效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1924231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux 文件读写描述符重定向 Linux 一切皆文件缓冲区】

文章目录 一、文件的读写操作二、文件描述符三、文件重定向四、理解 Linux 一切皆文件五、文件缓冲区 一、文件的读写操作 文件内容属性 当文件没有被操作的时候&#xff0c;一般文件还是在磁盘当中 文件操作文件内容的操作文件属性的操作&#xff0c;文件操作有可能即改变内容…

实战:docker式部署frp内网穿透-2024.7.13(测试成功)

前提 首先就需要准备好一台云服务器&#xff0c;用于提供公网 IP 和流量转发。至于购买哪家的云服务产品&#xff0c;本着能省则省的原则&#xff0c;这个当然是哪家便宜用哪家呢。 我手上目前有闲置的腾讯云的服务器&#xff0c;刚好可以用来作为内网穿透的机器&#xff0c;…

MySQL篇十:事务

文章目录 前言1. 什么是事务&#xff1f;2. 为什么会出现事务3. 事务的版本支持4. 事务提交方式5. 事务常见操作方式6. 事务隔离级别6.1 如何理解隔离性16.2 如何理解隔离性26.2.1 读-写6.2.2 undo 日志6.2.3 模拟 MVCC6.2.4 RR 与 RC的本质区别 前言 CURD不加控制&#xff0c;…

【探索Linux】P.39(传输层 —— TCP的三次 “握手” 和四次 “挥手” )

阅读导航 引言一、TCP的三次握手1. 简介2. 图解三次握手3. 名词解释&#xff08;1&#xff09;SYN&#xff08;同步序列编号&#xff09;包&#xff08;2&#xff09;SYN-ACK&#xff08;同步确认&#xff09;包&#xff08;3&#xff09;ACK&#xff08;确认&#xff09;包 4.…

【CTF-Crypto】数论基础-02

【CTF-Crypto】数论基础-02 文章目录 【CTF-Crypto】数论基础-021-16 二次剩余1-20 模p下-1的平方根*1-21 Legendre符号*1-22 Jacobi符号*2-1 群*2-2 群的性质2-3 阿贝尔群*2-4 子群2-11 群同态2-18 原根2-21 什么是环2-23 什么是域2-25 子环2-26 理想2-32 多项式环 1-16 二次剩…

C语言的神髓

从应用的角度出发&#xff0c;聊一聊C语言最精妙的部分。 ​​​​​​​ ​​​​​​​

unity 2020版本packManager没有AssetBundles

1.Packages->manifest.json打开manifest.json文件 2.添加"com.unity.assetbundlebrowser": "1.7.0", 保存即可

Readiris PDF Corporate / Business v23 解锁版安装教程 (PDF管理软件)

前言 Readiris PDF Corporate / Business 是一款高性能的 OCR&#xff08;光学字符识别&#xff09;软件&#xff0c;能够帮助用户将纸质文档、PDF 文件或图像文件转换为可编辑和可搜索的电子文本。该软件提供专业级的功能和特性&#xff0c;非常适合企业和商业使用。使用 Rea…

win10 docker-compose搭建ELK日志收集

elk的威名大家都知道&#xff0c;以前前司有专门的人维护&#xff0c;现在换了环境&#xff0c;实在不想上服务器看&#xff0c;所以就摸索下自己搭建&#xff0c;由于现场服务器是需要类似向日葵那样连接&#xff0c;我还是把日志弄回来&#xff0c;自己本地filebeat上传到es中…

【软件测试】LoadRunner | 基本概念 | VUG录制脚本 | 脚本加强 | Controller设计测试场景 | Analysis产生测试报告

文章目录 LoadRunner一、LoadRunner的基本概念功能:原理&#xff1a;组成&#xff1a; 二、开发测试脚本1.VUG录制脚本1.WebTours系统WebTours的配置&#xff1a;成功访问后进行注册 2.脚本录制3.运行&#xff08;回放&#xff09; 2.脚本加强1.插入事务插入函数:注意事项 2.插…

如何计算摄像头一个像素对应的实际面积(热成像仪选型1)

1. 前言 热成像仪广泛应用于缺陷检测&#xff0c;那么如何选择热成像仪&#xff0c;以满足缺陷检测需求&#xff1f;关键问题是&#xff1a;如何知道热成像仪能不能拍摄清楚我的缺陷呢&#xff1f;&#xff0c;要回答这个问题&#xff0c;就需要计算出热成像仪在最佳拍摄距离下…

2.5 OJ 网站的使用与作业全解

目录 1 OJ 网站如何使用 1.1 注册账户 1.2 登录账户 1.3 做题步骤 2 本节课的 OJ 作业说明 3 章节综合判断题 4 课时2作业1 5 课时2作业2 6 课时2作业3 1 OJ 网站如何使用 〇J 是英文 Online Judge 的缩写&#xff0c;中文翻译过来是在线判题。当用户将自己编写的代码…

浪潮天启防火墙TQ2000远程配置方法SSL-V偏、L2xx 配置方法

前言 本次设置只针对配置V偏&#xff0c;其他防火墙配置不涉及。建议把防火墙内外网都调通后再进行V偏配置。 其他配置可参考&#xff1a;浪潮天启防火墙配置手册 配置SSLVxx 在外网端口开启SSLVxx信息 开启SSLVxx功能 1、勾选 “启用SSL-Vxx” 2、设置登录端口号&#xff0…

ROS1 DWB 与 ROS2 DWA 比较

“DWA算法(dynamic window approach)是移动机器人在运动模型下推算(v,w)对应的轨迹,确定速度采样空间或者说是动态窗口(三种限制);在速度空间(v,w)中采样多组速度,并模拟这些速度在一定时间内的运动轨迹,通过一个评价函数对这些轨迹打分,选取最优的轨迹来驱动机器人运动”。ROS…

如何利用桌面工作计划软件制定自己的to do清单?

在我们的日常生活和工作中&#xff0c;经常会遇到各种各样的任务需要完成。如果没有一个明确的计划和安排&#xff0c;我们可能会感到混乱和压力&#xff0c;而桌面工作计划软件可以帮助我们更好地管理和规划我们的时间和任务。今天&#xff0c;我们就来聊聊如何利用这些工具&a…

职升网:二级建造师考试科目分析!

二级建造师考试包含三个主要科目&#xff0c;它们分别是《建设工程施工管理》、《建设工程法规及相关知识》以及《专业工程管理与实务》。以下是这三个科目的详细考试内容&#xff1a; 建设工程施工管理&#xff1a; 此科目作为建造师考试的基础科目&#xff0c;其核心内容是…

走进linux

1、为什么要使用linux 稳定性和可靠性&#xff1a; Linux内核以其稳定性而闻名&#xff0c;能够持续运行数月甚至数年而不需要重新启动。这对于服务器来说至关重要&#xff0c;因为它们需要保持长时间的稳定运行&#xff0c;以提供持续的服务 安全性&#xff1a; Linux系统…

酷克数据亮相第13届PostgreSQL中国技术大会,获数据库杰出贡献奖

7 月 12 日&#xff0c;第 13 届 PostgreSQL 中国技术大会在杭州盛大开幕。本次大会以“聚焦云端创新&#xff0c;汇聚智慧共享”为主题&#xff0c;邀请了国内外 PG 领域众多行业大咖、学术精英及技术专家&#xff0c;共同探讨数据库领域的发展趋势、技术创新和实践经验。酷克…

本地部署,使用ColorizeArtistic_gen.pth大模型进行图像上色

目录 引言 技术背景 模型架构 本地部署 运行结果 实验结果与分析 应用实例 结论 参考文献 引言 图像上色&#xff08;Image Colorization&#xff09;是指将黑白图像转换为彩色图像的技术。在数字化时代&#xff0c;这种技术可以用于修复旧照片、增强艺术作品以及在各…

FDL与Kettle功能对比分析之定时任务DDL

开发者在进行数据处理任务时&#xff0c; 一旦源数据库的表结构发生变化&#xff0c;而目标数据库没有及时进行同步&#xff0c;就会导致任务执行失败。DDL同步就是用来解决这一问题&#xff0c;它会自动识别源表结构变化&#xff0c;并及时更新到目标数据库中&#xff0c;保障…