一直使用swift 3,直到我更新了我的Xcode,它附带了swift 4,并且我必须开始使用可编码的可解码,但我很难生成结构来解码。这是json我试图变成一个对象
{
"status": "true",
"message": "Valid request",
"data": {
"user_id": "16",
"first_name": "Hamidouh",
"last_name": "Semix",
"other_name": null,
"fullname": "Hamidouh Semix",
"alias": null,
"about": "",
"sex_id": "1",
"sex": "Male",
"birth_date": "1989-08-17 00:00:00",
"relation_status_id": null,
"relation_status": null,
"relation_user_id": null,
"relation_user_first_name": null,
"relation_user_last_name": null,
"relation_user_fullname": null,
"location": null,
"contact": null,
"profile_pic": "698",
"profile_folder_name": "profile-picture",
"profile_pic_filename": "PROFILE-IMG-UPLOAD-1-16-20171222101217.jpg",
"cover_pic": "697",
"cover_folder_name": "cover-picture",
"cover_pic_filename": "COVER-IMG-UPLOAD-1-16-20171222100128.png",
"followers_list": {
"user_11": {
"id": "11",
"datetime": "2018-02-20 19:09:44"
}
},
"following_list": {
"user_1": {
"id": "1",
"datetime": "2018-03-01 09:53:24"
},
"user_3": {
"id": "3",
"datetime": "2018-02-19 09:18:18"
},
"user_24": {
"id": "24",
"datetime": "2017-12-22 09:58:17"
},
"user_260": {
"id": "260",
"datetime": "2018-02-19 09:18:16"
}
},
"mutual_list": {
"user_78": {
"id": "78",
"datetime": "2017-12-08 12:05:23"
}
},
"request_counter": "0",
"dream_destination_list": null,
"hidden_content_list": null,
"email": "semixss.hamidouh@gmail.com",
"username": null,
"password": "84bcec2f89a4f8cdd17b4a98d1a6cbf69bc9efe657d36a09b2d423fa3030772ab8ba9e24",
"salt": "owkLO",
"social_media_auth": null,
"social_media_id": null,
"date_created": "2017-08-18 14:00:22",
"last_seen": "2018-03-16 13:53:57",
"is_suspended": null,
"is_notified": null,
"approve_token": "8f82fbac62ded7260a3faa45460719a1390e3e216c6ebf3c4794f2da627138b9",
"device_token": null,
"language_id": null,
"language_machine_name": null,
"language_label": null,
"active": "1"
}
}
目前这些是我能够为json
生成的结构struct user : Decodable {
let status: String
let message: String
let data: userData
}
struct userData : Decodable {
let user_id: Int
let first_name: String
let last_name: String
let other_name: String
let fullname: String
let alias: String
let about: String
let sex_id: Int
let sex: String
let birth_date: String
let relation_status_id: Int
let relation_status: String
let relation_user_id: Int
let relation_user_first_name: String
let relation_user_last_name: String
let relation_user_fullname: String
let location: String
let contact: String
let profile_pic: Int
let profile_folder_name: String
let profile_pic_filename: String
let cover_pic: Int
let cover_folder_name: String
let cover_pic_filename: String
let followers_list: Int
let following_list: Int
let mutual_list: Int
let request_counter: Int
let dream_destination_list: Int
let hidden_content_list: Int
let email: String
let username: String
let password: String
let salt: String
let social_media_auth: String
let social_media_id: Int
let date_created: String
let last_seen: String
let is_suspended: String
let is_notified: String
let approve_token: String
let device_token: String
let language_id: Int
let language_machine_name: String
let language_label: String
let active: Int
}
这是我为尝试解析此
而编写的解码代码
//send request to server
guard let loginUrl = URL(string: "https://xxxxxx.com/api/index.php/Auth/login") else {return}
//request url
var request = URLRequest(url: loginUrl)
// method to pass data
request.httpMethod = "POST"
let body = "username=\(usernameVar)&password=\(passwordVar)"
request.httpBody = body.data(using: String.Encoding.utf8)
//launch session
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
guard let data = data else {return}
do {
//let json = try JSONSerialization.jsonObject(with: data, options: [])
//print(json)
let userDetails = try JSONDecoder().decode(user.self, from: data)
for details in userDetails {
print(details.message)
}
}catch{
print(error)
}
}
task.resume()
这是错误
typeMismatch(Swift.Array,Swift.DecodingError.Context(codingPath:[],debugDescription:"期望解码数组,但却找到了一个字典。",underlyingError:nil))
答案 0 :(得分:0)
您应该将错误消息更改为更有用的错误消息Lol。
您还没有在json中考虑可选值。请记住,String
和String?
之间存在差异,json有效内容中有多个值返回nil。在swift结构中,您需要将这些字段标记为Optionals
。
您也有不匹配的类型。您返回的所有类型均为String
或String?
而非Int
。这些只是String?
返回的数字。此有效负载中也嵌套了Dictionary
种类型。 followers_list
是一个字典,因此您需要使用名为List
的属性创建一个新结构,并在UserData
结构中设置这些"列表"的类型。到[String:List]
当您对解码时抛出的错误类型(以及大多数CocoaTouch Framework)感到困惑时,这些错误都是NSErrors
。您可以将错误的值打印到控制台,它会准确地告诉您退出示波器的错误。 IE:
valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [__lldb_expr_20.user.(CodingKeys in _992B1F7B4C3E0BAC48AEA280B9410D72).data, __lldb_expr_20.userData.,
debugDescription: "Expected String value but found null instead.", underlyingError: nil))
上述错误消息告诉您CodingKey...userData
设置为期待String
,但有null
(无)。
下面是你当前的结构应该是什么样的:
struct User : Decodable {
let status: String
let message: String
let data: userData
}
struct List: Decodable {
var id: String?
var datetime: String?
}
struct UserData : Decodable {
let user_id: String
let first_name: String
let last_name: String
let other_name: String?
let fullname: String
let alias: String?
let about: String
let sex_id: String
let sex: String
let birth_date: String
let relation_status_id: String?
let relation_status: String?
let relation_user_id: String?
let relation_user_first_name: String?
let relation_user_last_name: String?
let relation_user_fullname: String?
let location: String?
let contact: String?
let profile_pic: String
let profile_folder_name: String
let profile_pic_filename: String
let cover_pic: String
let cover_folder_name: String
let cover_pic_filename: String
let followers_list: [String:List]
let following_list: [String:List]
let mutual_list: [String:List]
let request_counter: String
let dream_destination_list: List?
let hidden_content_list: List?
let email: String
let username: String?
let password: String?
let salt: String
let social_media_auth: String?
let social_media_id: String?
let date_created: String
let last_seen: String
let is_suspended: String?
let is_notified: String?
let approve_token: String
let device_token: String?
let language_id: String?
let language_machine_name: String?
let language_label: String?
let active: String
}
松散蛇案例并使用CodingKeys
来遵循Swift命名约定或使用具有您关心的值的公共结构(您不必对整个JSON有效负载进行建模)使用私有结构对JSON进行建模并使用自定义init(from decoder: Decoder)
using this answer设置值。