在UserDefaults中存储数组遇错误:插入非属性列表对象异常
解决UserDefaults存储自定义结构体数组报错问题
错误信息
Thread 1: "Attempt to insert non-property list object (
"VPQuizzy.UserDetails(name: "Wewewe", userName:
"Wefrfrferf", password: "wedwedwedwed")"
) for key
userDataList"
问题原因
UserDefaults仅支持存储属性列表类型(如NSString、NSNumber、NSDate、NSData、NSArray、NSDictionary等),自定义的UserDetails结构体不属于这类可直接存储的类型,直接存入就会触发上述错误。必须将结构体序列化为Data后再存储,读取时反序列化为结构体数组。
解决方案
1. 让自定义结构体遵循Codable协议
修改UserDetails结构体,添加Codable协议支持(同时修正属性名符合Swift命名规范):
struct UserDetails: Codable { let name: String let userName: String let password: String }
2. 重构存储与读取逻辑
替换原有的读写方法,使用JSONEncoder将结构体数组编码为Data存入UserDefaults,读取时用JSONDecoder解码:
读取并更新用户列表的方法
var userList = [UserDetails]() func setUserData(name: String?, userName: String?, password: String?) { guard let name = name, let userName = userName, let password = password else { print("Please check again the code") return } // 读取已存储的用户列表 if let storedData = UserData.data(forKey: UserDefaultKey.userDataList.rawValue), let storedUserList = try? JSONDecoder().decode([UserDetails].self, from: storedData) { userList = storedUserList } else { userList = [] } userList.append(UserDetails(name: name, userName: userName, password: password)) print(userList) setUserData(userList) }
存储用户列表的方法
func setUserData(_ userList: [UserDetails]) { do { let encodedData = try JSONEncoder().encode(userList) UserData.set(encodedData, forKey: UserDefaultKey.userDataList.rawValue) } catch { print("编码用户列表失败: \(error.localizedDescription)") } }
额外提示
- 生产环境中,不要用UserDefaults存储密码这类敏感信息,建议使用Keychain进行安全存储。
- 确保
UserDefaultKey.userDataList.rawValue是正确的字符串键值。
内容的提问来源于stack exchange,提问作者Vishvesh Pratap Singh
相关产品推荐
相关产品推荐

