如何使用UserDefaults在Swift中保存/检索字符串,布尔值和其他数据?
创建Today小部件,我UserDefaults(suiteName:)用来保存一些数据.在我正在使用的主要应用程序中UserDefaults.standard().这是扩展无法读取(或可以吗?),这就是我使用suiteName:构造函数的原因.
用户UserDefaults.standard()在主应用中持久保存的数据需要在扩展中可用.
在这个时候,我坚持两者,以便可以共享价值观
UserDefaults.standard().set:...forKey:...
UserDefaults(suiteName:...)().set:...forKey:...
...
Run Code Online (Sandbox Code Playgroud)
问题是我应该UserDefaults.standard()放在一起,只是UserDefaults(suiteName:)在我的应用程序中使用,或者这是不好的做法,如果是这样,为什么?
编辑:我正在使用App组容器.为了澄清我要问我应该在我的项目中用suiteName替换standard()吗?
我曾经使用以下语句将重要的应用程序数据(如登录凭据)保存到 UserDefaults 中:
UserDefaults.standard.set("sample@email.com", forKey: "emailAddress")
Run Code Online (Sandbox Code Playgroud)
现在,我知道 SwiftUI 引入了新的属性包装器,称为:
@AppStorage
谁能解释一下新功能的工作原理?
我有一个简单的函数,我将一个对象保存到用户默认值,以便以后加载它,它看起来像这样:
func saveGame() {
// hero is an instance of the class Hero, subclassed from SKSpriteNode
UserDefaults.standard.set(hero, forKey: HeroObjectKey)
}
Run Code Online (Sandbox Code Playgroud)
我收到错误:
2017-03-13 21:15:33.124271 Castle [5405:5208658] [User Defaults]尝试设置非属性列表对象名称:'hero'纹理:['hero1.ico'(32 x 32)]位置:{0,0}缩放:{1.00,1.00}大小:{32,32} anchor:{0.5,0.5} rotation:0.00作为关键heroObjectKey的NSUserDefaults/CFPreferences值
这是因为我无法保存自己的自定义对象,还是不喜欢对象中的某些属性值?
注意:有一个非常类似的问题部分地解决了我的问题,但由于Swift3与他们使用的任何东西之间的差异,那里接受的答案对我不起作用.所以我会在这里提供答案.
我正在尝试使用 AppStorage 属性包装器在用户默认值中存储字符串数组,如下所示:
@AppStorage("History") var history: [String] = ["End of history"]
Run Code Online (Sandbox Code Playgroud)
但是我得到了错误No exact matches in call to initializer
如果我没记错的话,这是 AppStorage 的限制吗?因为 UserDefaults 可以存储数组?我可以使用什么解决方法?
我正在测试一个依赖于 UserDefaults 实例的类。按照此处找到的示例代码,我创建并设置实例,如下所示:
override func setUp() {
super.setUp()
defaults = UserDefaults(suiteName: #file)
defaults.removePersistentDomain(forName: #file)
}
Run Code Online (Sandbox Code Playgroud)
运行测试后,将在与此测试类相同的目录中创建一个 plist 文件。如果我的测试文件被命名,TestFile.swift则 plist 的名称为TestFile.swift.plist. 我很确定这是在调用suiteName:上面的初始化程序时生成的。我的问题是:测试完成后如何删除该文件?我尝试在测试方法中调用removeSuite(named: #file)、removeVolatileDomain(forName: #file)和 ,但没有成功。打电话似乎也没有帮助。removePersistentDomain(forName: #file)tearDownsynchronize()
我试图在 Swift 中检索自定义对象数组,但出现错误
"UserInfo={NSDebugDescription=value for key 'root' was of unexpected class 'NSArray'. Allowed classes are '{(MusicCloud.Playlist)}"
Run Code Online (Sandbox Code Playgroud)
我的项目是一个音乐播放器,所以我有一个 Song 对象和一个 Playlist 对象,其中有一个名称并列出歌曲。
我已经对对象模型进行了编码:
class Playlist: NSObject, NSCoding{
var name: String
var songs: [Song]
var image: UIImage
override init() {
self.name = ""
self.songs = []
self.image = UIImage()
}
init(name: String, songs: [Song], image: UIImage) {
self.name = name
self.songs = songs
self.image = image
}
required convenience init(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObject(forKey: "name") as! String
let songs …Run Code Online (Sandbox Code Playgroud) 我分配了一组颜色,希望将其保存到 UserDefaults 中。我有默认的灰色、绿色、橙色和红色,但我想允许颜色选择器更改绿色、橙色和红色。默认值在我的模拟器中有效并显示,但是当我尝试更改数组中的颜色时,出现错误“尝试插入非属性列表对象(\n“50% 灰色”、\n 绿色、\n ” kCGColorSpaceModelRGB 0.647194 0.881984 0.980039 1 “,\n 红色\n) 用于关键 SavedColors。” 我相信这是因为颜色选择器试图插入不同类型的颜色?看起来它可能正在尝试插入 CGColor 或 CGColorSpace ?
这是我的项目代码:
import SwiftUI
import Foundation
import Combine
class UserSettings: ObservableObject {
@Published var colors: [Color] {
didSet {
UserDefaults.standard.set(colors, forKey: "SavedColors")
}
}
init() {
self.colors = UserDefaults.standard.object(forKey: "SavedColors") as? [Color] ?? [Color.gray.opacity(0.5), Color.green, Color.orange, Color.red]
}
}
struct CustomizeView: View {
@ObservedObject var savedColors = UserSettings()
var body: some View {
NavigationView {
Form {
if #available(iOS 14.0, *) …Run Code Online (Sandbox Code Playgroud) 我的应用程序使用一个可编码的结构,如下所示:
public struct UserProfile: Codable {
var name: String = ""
var completedGame: Bool = false
var levelScores: [LevelScore] = []
}
Run Code Online (Sandbox Code Playgroud)
AJSONEncoder()已用于将UserProfiles的编码数组保存为用户默认值。
在即将到来的更新中,我想向这个UserProfile结构添加一个新属性。这在某种程度上可能吗?
或者我是否需要创建一个具有相同属性和一个新属性的新 Codable 结构,然后将所有值复制到新结构中,然后开始使用该新结构代替UserProfile之前使用该结构的任何地方?
如果我只是向结构体添加一个新属性,那么我将无法加载之前编码的UserProfiles数组,因为结构体将不再具有匹配的属性。当我使用此代码加载已保存的用户时:
if let savedUsers = UserDefaults.standard.object(forKey: "SavedUsers") as? Data {
let decoder = JSONDecoder()
if let loadedUsers = try? decoder.decode([UserProfile].self, from: savedUsers) {
Run Code Online (Sandbox Code Playgroud)
loadedUsers如果在UserProfile编码和保存时具有的属性不包含结构的所有当前属性,则不解码UserProfile。
有关更新保存的结构属性的任何建议?或者我必须走很长的路并重新创建,因为我之前没有提前计划要包含此属性?
谢谢你的帮助!
我目前正在努力找出正确放置 .register() 方法的位置,以设置 UserDefaults 的初始/默认值(在应用程序的每次启动时)。
这是我尝试在 Xcode 随项目生成的“App”文件中初始化它的地方:
import SwiftUI
@main
struct TestApp: App {
init() {
//Sets default values for the user defaults that have not yet been set and should not return 0/false
UserDefaults.standard.register(defaults: [
"selectedRoundLength": 1
]
)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这似乎并没有真正起作用。有人对此有意见吗?
userdefaults ×10
swift ×8
ios ×5
swiftui ×4
appstorage ×1
arrays ×1
ios14 ×1
nscoding ×1
nsobject ×1
properties ×1
struct ×1
swift3 ×1
xcode ×1
xctest ×1