从 NSUserDefaults 检索自定义对象
Retrieving custom Object from NSUserDefaults
我有一本价值观字典
class Objects {
let values = [
"AAA": ["AAAAAAA", "111111111"],
"BBB": ["BBBBBBBB", "2222222"],
"CCC": ["CCCCCCCC", "3333333333"],
"DDD": ["DDDDDD", "44444444"],
]
}
我将其转换为自定义对象并显示在表格视图中。
struct Object {
var heading : String!
var imageName: String!
}
然后用户可以 select 两个对象存储在 UserDefaults
let defaults = UserDefaults.standard
func addObject(_ object1: String, object2: String) {
// Get objects for user
var userObjects = fetchObjectsFromUserDefaults()
// Add to user currencies
userObjects.append([object1,object2])
//Update user defaults value for key
// [ [Object1, Object2], [Object1, Object2] ]
defaults.set(userObject, forKey: "userCurrencies")
}
// Gets [[String]] values from user defaults for key
func fetchObjectsFromUserDefaults() -> [[String]] {
if let objects = UserDefaults.standard.value(forKey: "userObjects") {
return objects as! [[String]]
} else {
return []
}
}
// Uses [[String]] values and turns them into objects by using the dictionary to determine property values
func getObject() -> [[Object]] {
let userObject = fetchObjectsFromUserDefaults()
// [ [Object1, Object2], [Object1, Object2] ]
let object = Object()
var fetchedObject = [[Object]]()
if !userObjects.isEmpty {
for c in userObjects {
var set = [Object]()
if let val = object.available[c[0]] {
set.append(Currency(currencyTitle: c[0], imageName: val[0] ))
}
if let val2 = object.available[c[1]] {
set.append(Currency(currencyTitle: c[0], imageName: val2[0] ))
}
if !set.isEmpty {
fetchedObjects.append(set)
}
}
return fetchedObjects
}
return [[]]
}
视图控制器
在这里,我将对象加载到 TableView
let fetched = dataManager.getObjects
print(fetched)
self.objects = fetched()
然而这打印出来
(Function)
我哪里做错了,他们是一种更好的存储和检索用户默认数据的方法吗?我觉得这已经结束了,有一种更快捷、更安全的方法。
步骤 1.
制作你的结构Codable
。如果 struct
的所有成员都是 Codable
,幸运的是 String
是 Codable
,编译器将为您编写所有函数,所以它只是:
struct Object: Codable {
var heading : String!
var imageName: String!
}
第 2 步
Codable
的问题在于它与 Data
相互转换,但您想与 Dictionary
相互转换。幸运的是 JSONSerialization 从 Data
转换为 Dictionary
所以创建一个新的协议并给它一个带有协议扩展的默认实现:
protocol JSONRepresentable {
init?(json: [String: Any])
func json() -> [String: Any]
}
extension JSONRepresentable where Self: Codable {
init?(json: [String:Any]) {
guard let value = (try? JSONSerialization.data(withJSONObject: json, options: []))
.flatMap ({ try? JSONDecoder().decode(Self.self, from: [=11=]) }) else {
return nil
}
self = value
}
func json() -> [String:Any] {
return (try? JSONEncoder().encode(self))
.flatMap { try? JSONSerialization.jsonObject(with: [=11=], options: []) } as? [String: Any] ?? [:]
}
}
步骤 3.
使您的结构符合 JSONRepresentable
struct Object: Codable, JSONRepresentable {
var heading : String!
var imageName: String!
}
第 4 步
将您的对象放入 Userdefaults 并再次取出:
let o = Object.init(heading: "s", imageName: "a").json()
UserDefaults.standard.set(o, forKey: "test")
print(Object.init(json: UserDefaults.standard.dictionary(forKey: "test") ?? [:]))
如果你想尝试,这里是整个游乐场:
import UIKit
struct Object: Codable, JSONRepresentable {
var heading : String!
var imageName: String!
}
protocol JSONRepresentable {
init?(json: [String: Any])
func json() -> [String: Any]
}
extension JSONRepresentable where Self: Codable {
init?(json: [String:Any]) {
guard let value = (try? JSONSerialization.data(withJSONObject: json, options: []))
.flatMap ({ try? JSONDecoder().decode(Self.self, from: [=14=]) }) else {
return nil
}
self = value
}
func json() -> [String:Any] {
return (try? JSONEncoder().encode(self))
.flatMap { try? JSONSerialization.jsonObject(with: [=14=], options: []) } as? [String: Any] ?? [:]
}
}
let o = Object.init(heading: "s", imageName: "a").json()
UserDefaults.standard.set(o, forKey: "test")
print(Object.init(json: UserDefaults.standard.dictionary(forKey: "test") ?? [:]))
我有一本价值观字典
class Objects {
let values = [
"AAA": ["AAAAAAA", "111111111"],
"BBB": ["BBBBBBBB", "2222222"],
"CCC": ["CCCCCCCC", "3333333333"],
"DDD": ["DDDDDD", "44444444"],
]
}
我将其转换为自定义对象并显示在表格视图中。
struct Object {
var heading : String!
var imageName: String!
}
然后用户可以 select 两个对象存储在 UserDefaults
let defaults = UserDefaults.standard
func addObject(_ object1: String, object2: String) {
// Get objects for user
var userObjects = fetchObjectsFromUserDefaults()
// Add to user currencies
userObjects.append([object1,object2])
//Update user defaults value for key
// [ [Object1, Object2], [Object1, Object2] ]
defaults.set(userObject, forKey: "userCurrencies")
}
// Gets [[String]] values from user defaults for key
func fetchObjectsFromUserDefaults() -> [[String]] {
if let objects = UserDefaults.standard.value(forKey: "userObjects") {
return objects as! [[String]]
} else {
return []
}
}
// Uses [[String]] values and turns them into objects by using the dictionary to determine property values
func getObject() -> [[Object]] {
let userObject = fetchObjectsFromUserDefaults()
// [ [Object1, Object2], [Object1, Object2] ]
let object = Object()
var fetchedObject = [[Object]]()
if !userObjects.isEmpty {
for c in userObjects {
var set = [Object]()
if let val = object.available[c[0]] {
set.append(Currency(currencyTitle: c[0], imageName: val[0] ))
}
if let val2 = object.available[c[1]] {
set.append(Currency(currencyTitle: c[0], imageName: val2[0] ))
}
if !set.isEmpty {
fetchedObjects.append(set)
}
}
return fetchedObjects
}
return [[]]
}
视图控制器
在这里,我将对象加载到 TableView
let fetched = dataManager.getObjects
print(fetched)
self.objects = fetched()
然而这打印出来
(Function)
我哪里做错了,他们是一种更好的存储和检索用户默认数据的方法吗?我觉得这已经结束了,有一种更快捷、更安全的方法。
步骤 1.
制作你的结构Codable
。如果 struct
的所有成员都是 Codable
,幸运的是 String
是 Codable
,编译器将为您编写所有函数,所以它只是:
struct Object: Codable {
var heading : String!
var imageName: String!
}
第 2 步
Codable
的问题在于它与 Data
相互转换,但您想与 Dictionary
相互转换。幸运的是 JSONSerialization 从 Data
转换为 Dictionary
所以创建一个新的协议并给它一个带有协议扩展的默认实现:
protocol JSONRepresentable {
init?(json: [String: Any])
func json() -> [String: Any]
}
extension JSONRepresentable where Self: Codable {
init?(json: [String:Any]) {
guard let value = (try? JSONSerialization.data(withJSONObject: json, options: []))
.flatMap ({ try? JSONDecoder().decode(Self.self, from: [=11=]) }) else {
return nil
}
self = value
}
func json() -> [String:Any] {
return (try? JSONEncoder().encode(self))
.flatMap { try? JSONSerialization.jsonObject(with: [=11=], options: []) } as? [String: Any] ?? [:]
}
}
步骤 3.
使您的结构符合 JSONRepresentable
struct Object: Codable, JSONRepresentable {
var heading : String!
var imageName: String!
}
第 4 步
将您的对象放入 Userdefaults 并再次取出:
let o = Object.init(heading: "s", imageName: "a").json()
UserDefaults.standard.set(o, forKey: "test")
print(Object.init(json: UserDefaults.standard.dictionary(forKey: "test") ?? [:]))
如果你想尝试,这里是整个游乐场:
import UIKit
struct Object: Codable, JSONRepresentable {
var heading : String!
var imageName: String!
}
protocol JSONRepresentable {
init?(json: [String: Any])
func json() -> [String: Any]
}
extension JSONRepresentable where Self: Codable {
init?(json: [String:Any]) {
guard let value = (try? JSONSerialization.data(withJSONObject: json, options: []))
.flatMap ({ try? JSONDecoder().decode(Self.self, from: [=14=]) }) else {
return nil
}
self = value
}
func json() -> [String:Any] {
return (try? JSONEncoder().encode(self))
.flatMap { try? JSONSerialization.jsonObject(with: [=14=], options: []) } as? [String: Any] ?? [:]
}
}
let o = Object.init(heading: "s", imageName: "a").json()
UserDefaults.standard.set(o, forKey: "test")
print(Object.init(json: UserDefaults.standard.dictionary(forKey: "test") ?? [:]))