当前位置: 首页 > news >正文

Swift 中 User Defaults 的读取和写入

在这里插入图片描述

文章目录

    • 前言
    • 介绍 User Defaults
    • 共享 User Defaults
    • User Defaults 存储数据类型
    • 响应更改
    • 监控 User Defaults 更改
    • 覆盖User Defaults 设置
    • 考虑的替代方案
      • Keychain 用于安全性
      • 用于跨平台的 CloudKit
    • 结论

前言

User Defaults 是 Swift 应用程序存储在应用启动之间保持的首选项的首选解决方案。它是由属性列表(plist)文件支持的键-值存储。由于这种类型的支持存储,你需要了解支持的存储类型。

在使用 User Defaults 时有一些最佳实践。我还可以根据在数十个应用程序中使用它的实施经验,推荐特定的解决方案。让我们深入研究一下!

介绍 User Defaults

应用程序通常使用 User Defaults 来存储用户的首选项。你可以存储首选项,例如用户最喜欢的股票或保存特定用户状态,例如“用户已看到引导”。

存储这些首选项的代码可以如下所示:

UserDefaults.standard.set(true, forKey: "has-seen-onboarding")
UserDefaults.standard.set(["AAPL", "TSLA"], forKey: "favorite-stocks")print(UserDefaults.standard.bool(forKey: "has-seen-onboarding")) 
// 打印:true
print(UserDefaults.standard.array(forKey: "favorite-stocks")) 
// 打印:["AAPL", "TSLA"]

在这种情况下,我们使用了标准 User Defaults 容器。在大多数情况下,这将足够。但是,你可能希望考虑使用组 User Defaults 。

共享 User Defaults

与其他应用程序和扩展共享 User Defaults

使用所谓的应用组,你可以与其他应用程序和扩展共享 User Defaults 容器。我强烈建议从一开始就使用这种技术,即使现在可能没有共享首选项的需要,但如果你添加需要从主应用程序中读取或写入首选项的扩展,以后你会感谢自己的。

要配置应用组,你需要向项目设置中添加一个新的功能:

你可以通过添加应用组功能来开始与其他应用程序和扩展共享 User Defaults。

你可以在苹果的文档中找到详细的说明。配置后,你可以使用组标识符创建新实例:

extension UserDefaults {static let group = UserDefaults(suiteName: "group.your.identifier")
}

现在,你可以通过使用静态属性来访问共享的组容器:

UserDefaults.group.set(["AAPL", "TSLA"], forKey: "favorite-stocks")

任何使用相同应用组的应用程序或扩展现在都可以读取和写入最喜欢的股票。我在 Stock Analyzer 中使用此技术,根据主应用程序中配置的最喜欢的股票填充小部件。

User Defaults 存储数据类型

属性列表必须支持你存储在 User Defaults 中的对象。只要你尝试写入不受支持的对象,你将立即遇到以下错误:

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Attempt to insert non-property list object UserDefaults.Stock(symbol: “AAPL”) for key last-opened-stock’

在这种情况下,我试图存储一个可编码的对象:

struct Stock: Decodable {let symbol: String
}UserDefaults.group.set(Stock(symbol: "AAPL"), forKey: "last-opened-stock")

每当你遇到此类异常时,你必须在存储数据之前将数据转换。你可以使用 JSONEncoder 将实例编码为数据,并在读取值时解码它。

User Defaults 支持以下类型:

  • 数据
  • 字符串
  • 数字(NSNumber)
  • 日期
  • 数组
  • 字典
  • 布尔值

如果你的类型不在此列表中,你需要找到一种将其转换为任何受支持类型的方法。

响应更改

尽管你可以使用 didChangeNotification 来观察更改,但我建议查看类似于 User Defaults Property Wrapper 的托管解决方案,用于实时监视更改。

监控 User Defaults 更改

在处理与 User Defaults 互动的功能时,你希望有一种实时监视更改的方法。为解决这个问题,我在 RocketSim 中构建了一个 User Defaults 编辑器,允许你实时编辑和监视键-值对。

例如,我在以下视频中正在开发 WeTransfer 应用程序中显示的工具提示。工具提示应该每位用户只显示一次,我希望确保 User Defaults 键 hasShownUploadFilesTooltip 相应地更新。你可以通过单击执行按钮并选择 User Defaults plist 文件来打开编辑器。

RocketSim 的 User Defaults 编辑器允许你实时编辑和查看 User Defaults 值。

编辑器不断监视值,当值更改时会闪烁蓝色背景颜色。与此同时,我可以使用开关重置该值,并使用 RocketSim 重新启动应用程序,以查看工具提示是否再次显示。

你可以想象这大大加快了测试依赖于 User Defaults 的实施的工作流程。最好的是你可以免费开始并使用标准套件测试编辑器,只需从 Mac App Store 安装 RocketSim 即可。

覆盖User Defaults 设置

出于调试目的覆盖User Defaults 设置

虽然使用 RocketSim 有助于实现最佳更改和调试,但你可能希望在调试过程中使用方案设置来覆盖User Defaults 设置。

考虑的替代方案

在大多数情况下,User Defaults 是一个很好的解决方案,但如果你存储敏感数据或希望跨设备访问数据,你可能希望探索其他解决方案。

Keychain 用于安全性

User Defaults 不足以存储敏感数据。用户凭据、API 密钥或其他敏感数据应存储在钥匙串中。

用于跨平台的 CloudKit

如果希望首选项可以从安装了你的应用程序的其他 Apple 设备访问,请考虑使用 NSUbiquitousKeyValueStore。它是一个类似的键-值存储,但使用 iCloud 作为支持存储。

结论

你可以使用 User Defaults 存储首选项并在应用启动之间捕获状态。应用组非常适合与其他应用程序和扩展共享首选项,你需要密切关注可以存储的数据类型。通过监视支持存储,你将确保没有意外存储的数据。当需要跨设备访问数据或需要存储敏感数据时,最好查看替代解决方案。

相关文章:

  • docker搭建xxl-job
  • 配置typroa上传图片到gitee
  • Python作业答疑_6.22~6.25
  • debianubuntu的nvidia驱动升级
  • unity 2d 入门 飞翔小鸟 下坠功能且碰到地面要停止 刚体 胶囊碰撞器 (四)
  • APM Server监控
  • cs制作木马和钓鱼邮件
  • C实现的双向链表队列
  • 【Docker】Swarm的ingress网络
  • (分类)KNN算法- 参数调优
  • TimeGPT:时间序列预测模型实例
  • 「Swift」取消UITableView起始位置在状态栏下方开始
  • 10、外观模式(Facade Pattern,不常用)
  • Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境
  • 网站提示不安全?
  • 【css3】浏览器内核及其兼容性
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 【刷算法】从上往下打印二叉树
  • canvas 五子棋游戏
  • css系列之关于字体的事
  • Java超时控制的实现
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Netty 4.1 源代码学习:线程模型
  • rc-form之最单纯情况
  • SpringBoot几种定时任务的实现方式
  • text-decoration与color属性
  • TypeScript迭代器
  • 从零开始在ubuntu上搭建node开发环境
  • 使用parted解决大于2T的磁盘分区
  • 双管齐下,VMware的容器新战略
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​马来语翻译中文去哪比较好?
  • #laravel 通过手动安装依赖PHPExcel#
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (55)MOS管专题--->(10)MOS管的封装
  • (BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等(1)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET_WebForm_layui控件使用及与webform联合使用
  • @ConditionalOnProperty注解使用说明
  • @property @synthesize @dynamic 及相关属性作用探究
  • [20160902]rm -rf的惨案.txt
  • [AHK V2]鼠标悬停展开窗口,鼠标离开折叠窗口
  • [Angular] 笔记 18:Angular Router
  • [ArcPy百科]第三节: Geometry信息中的空间参考解析
  • [C#]winform部署yolov9的onnx模型
  • [C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测
  • [C#学习笔记]LINQ
  • [C++] Boost智能指针——boost::scoped_ptr(使用及原理分析)
  • [C++][opencv]基于opencv实现photoshop算法可选颜色调整