Swift 5 : 从我的变量中使用 Codable / Struct 创建 JSON
Swift 5 : Create JSON with Codable / Struct from my variables
我想创建一个 Codable 结构来保存来自用户配置文件的数据
假设 ios 用户用他的名字、姓氏、地址填写了一个表格,并放上了他的照片 (UIImage)) 并且该用户有一个唯一的 ID 。
我的 JSON 会像
{"Unique_ID" :"1234556778",
{"Name":"John",
"Last Name" : "Doe",
"adress" :
{"street": "21 jump street",
"country" : "USA"}
}
}
我尝试创建 Codable 但我认为它不是最优的 ,请您给我一些优化它的提示,或者告诉我我是否做错了像这样?
struct User_Profile: Codable {
let Unique_ID : String
let Data_Of_User : User_Profile_Data
}
struct User_Profile_Data: Codable {
let name : String
let last_name: String
let adress : User_Adress_Data
}
struct User_Adress_Data: Codable {
let street : String
let country: String
}
override func viewDidLoad() {
super.viewDidLoad()
let usernametest = "John"
let b = User_Adress_Data(street: "21 jump street", country: "USA")
let c = User_Profile_Data(name: usernametest, last_name: "Doe", adress: b)
let d = User_Profile(Unique_ID: "123456", Data_Of_User: c)
}
之后,我想用 Haneke swift(https://github.com/Haneke/HanekeSwift), or Datacache (https://github.com/huynguyencong/DataCache) 缓存它 我如何缓存我的 Codables? (例如,我没有看到任何 'set cache for json' 与哈内克)
最后,我想用 SwiftyJSON 获取后使用它:(https://github.com/SwiftyJSON/SwiftyJSON),我不知道我的Codables 足够可读。
感谢您的 idea/comment!
Codable 要求结构中的 属性 名称与对应的 json 匹配。
在你的 User_Profile_Data
结构中你有 name
而 json 包含 "Name"
并且你有 last_name
其中 json 包含 "Last Name"
。
解决此问题的一种方法是向您的结构添加一个 CodingKeys
枚举,告诉它如何映射属性。
所以在你的 User_Profile_Data
结构中我会添加:
enum CodingKeys: String, CodingKey { case name = "Name" case last_name = "Last Name" case adress }
由于您可以完全控制自己的结构并且不涉及任何集合,因此我建议将所有内容都放在一个结构中,而不是将其分散在许多不同的结构中:
struct UserProfile: Codable{
var id: String
var name: String
var lastname: String
var street: String
var country: String
}
关于缓存。正如您可以将此结构标记为 Codable
,它可以很容易地存储在 Userdefaults
中作为 Data
。 Userdefaults
上的这个扩展应该允许您以类型安全的方式访问 UserProfile
。
extension UserDefaults{
var userProfile: UserProfile?{
get{
guard let data = data(forKey: "userProfile") else{
return nil
}
return try? JSONDecoder().decode(UserProfile.self, from: data)
}
set{
set(try? JSONEncoder().encode(newValue), forKey: "userProfile")
}
}
}
用法示例:
//Write
UserDefaults.standard.userProfile = UserProfile(id: UUID().uuidString, name: "First", lastname: "Last", street: "nowhere", country: "atlantis")
//Read
let profile = UserDefaults.standard.userProfile
编辑:
编辑示例:
因为这是一个结构,所以每次发生变化时都会复制它。
所以读取 var 中的值。修改后保存到defaultStore.
var profile = UserDefaults.standard.userProfile
profile?.country = "newCountry"
UserDefaults.standard.userProfile = profile
您提供的示例无效 [=18=]。它看起来像是字典和数组的某种混合体。
所以让我们做一些调整:
{
"Unique_ID": "1234556778",
"Data_of_User": {
"First_Name": "John",
"Last_Name": "Doe",
"Address": {
"Street": "21 jump street",
"Country": "USA"
}
}
}
然后你可以创建如下所示的结构:
struct UserProfile: Codable {
let uniqueID: String
let userData: UserData
enum CodingKeys: String, CodingKey {
case uniqueID = "Unique_ID"
case userData = "Data_of_User"
}
}
struct UserData: Codable {
let firstName: String
let lastName: String
let address: Address
enum CodingKeys: String, CodingKey {
case firstName = "First_Name"
case lastName = "Last_Name"
case address = "Address"
}
}
struct Address: Codable {
let street: String
let country: String
enum CodingKeys: String, CodingKey {
case street = "Street"
case country = "Country"
}
}
我想创建一个 Codable 结构来保存来自用户配置文件的数据 假设 ios 用户用他的名字、姓氏、地址填写了一个表格,并放上了他的照片 (UIImage)) 并且该用户有一个唯一的 ID 。 我的 JSON 会像
{"Unique_ID" :"1234556778",
{"Name":"John",
"Last Name" : "Doe",
"adress" :
{"street": "21 jump street",
"country" : "USA"}
}
}
我尝试创建 Codable 但我认为它不是最优的 ,请您给我一些优化它的提示,或者告诉我我是否做错了像这样?
struct User_Profile: Codable {
let Unique_ID : String
let Data_Of_User : User_Profile_Data
}
struct User_Profile_Data: Codable {
let name : String
let last_name: String
let adress : User_Adress_Data
}
struct User_Adress_Data: Codable {
let street : String
let country: String
}
override func viewDidLoad() {
super.viewDidLoad()
let usernametest = "John"
let b = User_Adress_Data(street: "21 jump street", country: "USA")
let c = User_Profile_Data(name: usernametest, last_name: "Doe", adress: b)
let d = User_Profile(Unique_ID: "123456", Data_Of_User: c)
}
之后,我想用 Haneke swift(https://github.com/Haneke/HanekeSwift), or Datacache (https://github.com/huynguyencong/DataCache) 缓存它 我如何缓存我的 Codables? (例如,我没有看到任何 'set cache for json' 与哈内克)
最后,我想用 SwiftyJSON 获取后使用它:(https://github.com/SwiftyJSON/SwiftyJSON),我不知道我的Codables 足够可读。
感谢您的 idea/comment!
Codable 要求结构中的 属性 名称与对应的 json 匹配。
在你的 User_Profile_Data
结构中你有 name
而 json 包含 "Name"
并且你有 last_name
其中 json 包含 "Last Name"
。
解决此问题的一种方法是向您的结构添加一个 CodingKeys
枚举,告诉它如何映射属性。
所以在你的 User_Profile_Data
结构中我会添加:
enum CodingKeys: String, CodingKey { case name = "Name" case last_name = "Last Name" case adress }
由于您可以完全控制自己的结构并且不涉及任何集合,因此我建议将所有内容都放在一个结构中,而不是将其分散在许多不同的结构中:
struct UserProfile: Codable{
var id: String
var name: String
var lastname: String
var street: String
var country: String
}
关于缓存。正如您可以将此结构标记为 Codable
,它可以很容易地存储在 Userdefaults
中作为 Data
。 Userdefaults
上的这个扩展应该允许您以类型安全的方式访问 UserProfile
。
extension UserDefaults{
var userProfile: UserProfile?{
get{
guard let data = data(forKey: "userProfile") else{
return nil
}
return try? JSONDecoder().decode(UserProfile.self, from: data)
}
set{
set(try? JSONEncoder().encode(newValue), forKey: "userProfile")
}
}
}
用法示例:
//Write
UserDefaults.standard.userProfile = UserProfile(id: UUID().uuidString, name: "First", lastname: "Last", street: "nowhere", country: "atlantis")
//Read
let profile = UserDefaults.standard.userProfile
编辑: 编辑示例:
因为这是一个结构,所以每次发生变化时都会复制它。 所以读取 var 中的值。修改后保存到defaultStore.
var profile = UserDefaults.standard.userProfile
profile?.country = "newCountry"
UserDefaults.standard.userProfile = profile
您提供的示例无效 [=18=]。它看起来像是字典和数组的某种混合体。
所以让我们做一些调整:
{
"Unique_ID": "1234556778",
"Data_of_User": {
"First_Name": "John",
"Last_Name": "Doe",
"Address": {
"Street": "21 jump street",
"Country": "USA"
}
}
}
然后你可以创建如下所示的结构:
struct UserProfile: Codable {
let uniqueID: String
let userData: UserData
enum CodingKeys: String, CodingKey {
case uniqueID = "Unique_ID"
case userData = "Data_of_User"
}
}
struct UserData: Codable {
let firstName: String
let lastName: String
let address: Address
enum CodingKeys: String, CodingKey {
case firstName = "First_Name"
case lastName = "Last_Name"
case address = "Address"
}
}
struct Address: Codable {
let street: String
let country: String
enum CodingKeys: String, CodingKey {
case street = "Street"
case country = "Country"
}
}