[英]Decode JSON Data on Swift 4 returns nil
I'm trying to decode my json data with below function.我正在尝试使用以下函数解码我的 json 数据。 I had different Json format at first and It was working but whenI change json format, It started not to work.
起初我有不同的 Json 格式并且它正在工作,但是当我更改 json 格式时,它开始不起作用。 I try to do changes also in Structure code but nothing worked.
我也尝试在结构代码中进行更改,但没有任何效果。 What Am I missing?
我错过了什么? (Code is for first Json format so It needs to be work on second format too)
(代码适用于第一种 Json 格式,因此它也需要适用于第二种格式)
First JSON:第一个 JSON:
{
"status": 200,
"results": [
{
"group_matched": false,
"distance_mi": 4,
"content_hash": "1rT2lirUapfrYIYxSR2u0GtmRSLPsVki9kFj4ugs8JIq6",
"common_friends": [],
"common_likes": [],
"common_friend_count": 0,
"common_like_count": 0,
"connection_count": 0,
"_id": "5a2805ba779f34267d32d8b0",
"bio": "",
"birth_date": "1997-12-09T16:28:29.761Z",
"name": "John",
},
Second JSON:第二个JSON:
{
"meta": {
"status": 200
},
"data": {
"results": [
{
"type": "user",
"user": {
"_id": "545001b33bf179416a30bf7f",
"bio": "Ä°nstagram:",
"birth_date": "1992-12-09T17:12:49.957Z",
"name": "",
"photos": [
{
"id": "2eb1beec-6180-4d58-90fd-5f076da96af9",
"url": "",
"processedFiles": [
{
"url": "",
"height": 640,
"width": 640
},
{
"url": "",
"height": 320,
"width": 320
},
{
"url": "",
"height": 172,
"width": 172
},
{
"url": "",
"height": 84,
"width": 84
}
]
},
{
"id": "89d2bc07-d244-457b-b610-26ecd4e9e86d",
"url": "",
"processedFiles": [
{
"url": "",
"height": 640,
"width": 640
},
{
"url": "",
"height": 320,
"width": 320
},
{
"url": "",
"height": 172,
"width": 172
},
{
"url": "",
"height": 84,
"width": 84
}
]
},
{
"id": "0fcafc7e-d6e7-4cc5-891a-735971d6a5b2",
"url": "",
"processedFiles": [
{
"url": "",
"height": 640,
"width": 640
},
{
"url": "g",
"height": 320,
"width": 320
},
{
"url": "",
"height": 172,
"width": 172
},
{
"url": "",
"height": 84,
"width": 84
}
]
},
{
"id": "bac74531-09e7-4c5b-ac6c-cab36c4be587",
"url": "",
"processedFiles": [
{
"url": "",
"height": 640,
"width": 640
},
{
"url": "",
"height": 320,
"width": 320
},
{
"url": "",
"height": 172,
"width": 172
},
{
"url": "",
"height": 84,
"width": 84
}
]
},
{
"id": "3c216244-946a-4c58-8670-cc12c05801cb",
"url": "",
"processedFiles": [
{
"url": "",
"height": 640,
"width": 640
},
{
"url": "",
"height": 320,
"width": 320
},
{
"url": "",
"height": 172,
"width": 172
},
{
"url": "",
"height": 84,
"width": 84
}
]
},
{
"id": "-8672-488d-8b7e-f30b4560c56b",
"url": "",
"processedFiles": [
{
"url": "",
"height": 640,
"width": 640
},
{
"url": "",
"height": 320,
"width": 320
},
{
"url": "",
"height": 172,
"width": 172
},
{
"url": "",
"height": 84,
"width": 84
}
]
}
],
"gender": 1,
Struct Code:结构代码:
struct Photo: Codable{
var url: String?
var processedFiles: [processedFiles]?
}
struct User: Codable{
var group_matched: Bool?
var distance_mi: Int?
var common_friend_count: Int?
var name:String?
var profile_picture: String?
var instagram_id: String?
var photos: [Photo]?
}
class Results : Codable {
var results: [User] = []
static let sharedResults = Results()
private init() { }
var type: String?
func populateData(sender: Results){
print(sender)
results += sender.results
}
}
Decode Code:解码代码:
let jsonData = JSON(data: response.data!)
let jsonData2 = try? JSONSerialization.data(withJSONObject: jsonData["data"].object)
print(JSON(data: jsonData2!))
let decoder = JSONDecoder()
var response_class = Results.sharedResults
response_class = try decoder.decode(Results.self, from: jsonData2!)
Results.sharedResults.populateData(sender: response_class)
EDIT: I edit second JSON, It now has array of array.编辑:我编辑第二个 JSON,它现在有数组数组。 How Can I implement decoder keys for that second array?
如何为第二个数组实现解码器键?
In this case I would write a custom initializer with nestedContainer
to include the user
dictionary into the parent object在这种情况下,我将编写一个带有
nestedContainer
的自定义初始值nestedContainer
以将user
字典包含到父对象中
let jsonString = """
{
"meta": {
"status": 200
},
"data": {
"results": [
{
"type": "user",
"user": {
"_id": "545001b33bf179416a30bf7f",
"bio": "Ä°nstagram:hello",
"birth_date": "1992-12-09T17:12:49.957Z",
"name": "Hello"
},
"group_matched": false,
"distance_mi": 4
}
]
}
}
"""
struct Root : Decodable {
let meta : [String:Int]
let data : Result
}
struct Result : Decodable {
let results : [User]
}
struct User : Decodable {
let type : String
let groupMatched : Bool
let distanceMi : Int
let id, bio, birthDate, name : String
private enum CodingKeys : String, CodingKey {
case type, user, groupMatched = "group_matched", distanceMi = "distance_mi"
}
private enum UserKeys: String, CodingKey {
case id = "_id", bio, birthDate = "birth_date", name
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
type = try container.decode(String.self, forKey: .type)
groupMatched = try container.decode(Bool.self, forKey: .groupMatched)
distanceMi = try container.decode(Int.self, forKey: .distanceMi)
let userInfo = try container.nestedContainer(keyedBy: UserKeys.self, forKey: .user)
id = try userInfo.decode(String.self, forKey: .id)
bio = try userInfo.decode(String.self, forKey: .bio)
birthDate = try userInfo.decode(String.self, forKey: .birthDate)
name = try userInfo.decode(String.self, forKey: .name)
}
}
do {
let data = Data(jsonString.utf8)
let decoder = JSONDecoder()
let root = try decoder.decode(Root.self, from: data)
print(root)
} catch {
print("error: ", error)
}
By making the result of JSONDecoder().decode
an optional ( try?
), you are ensuring that you get nil
if the decoding goes wrong.通过将
JSONDecoder().decode
的结果JSONDecoder().decode
可选( try?
),您可以确保在解码出错时得到nil
。 You can catch decoding related issues quickly by implementing proper catch blocks.您可以通过实施适当的 catch 块来快速捕获与解码相关的问题。 Eg:
例如:
do {
let decoder = JSONDecoder()
let messages = try decoder.decode(Results.self, from: data)
print(messages as Any)
} catch DecodingError.dataCorrupted(let context) {
print(context)
} catch DecodingError.keyNotFound(let key, let context) {
print("Key '\(key)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch DecodingError.valueNotFound(let value, let context) {
print("Value '\(value)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch DecodingError.typeMismatch(let type, let context) {
print("Type '\(type)' mismatch:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch {
print("error: ", error)
}
Not a direct answer to your question, but surely will reduce other's time to understand which part of decoding is going wrong.不是对您问题的直接回答,但肯定会减少其他人了解解码哪一部分出错的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.