[英]Parse json inside another json string in swift4
I am trying to parse the json.我正在尝试解析 json。 But the problem is I have json inside to it another json String.
但问题是我有一个 json 里面有另一个 json 字符串。 Like :
喜欢 :
{
"count": 284,
"next": "http://X:X:X:X:8080/api/sensor/last5feed?page=2&search=XXXXX",
"previous": null,
"results": [
{
"id": 571,
"feed": "{'app_id': 'XXXXX', 'dev_id': 'XXXX', 'hardware_serial': 'XXXXX', 'port': 6, 'counter': 4290, 'payload_raw': 'AQEBIwXsF4IAAAA=', 'payload_fields': {'aamsg_type': 'weather', 'abstatus': 0, 'batteryV': 3.5, 'battery_low': 'no', 'humiP': 60.2, 'tempC': 15.2}, 'metadata': {'time': '2020-01-23T15:09:32.350967362Z', 'frequency': 868.1, 'modulation': 'LORA', 'data_rate': 'SF7BW125', 'airtime': 61696000, 'coding_rate': '4/5', 'gateways': [{'gtw_id': 'XXXXX', 'timestamp': 3227230963, 'time': '2020-01-23T15:09:32.326146Z', 'channel': 0, 'rssi': -98, 'snr': 4.8, 'rf_chain': 1, 'latitude': 57.124737, 'longitude': -2.1646452, 'altitude': 90, 'location_source': 'registry'}]}}",
"created_at": "2020-01-23T15:09:32.630326Z",
"sensor": 1
},
{
"id": 569,
"feed": "{'app_id': 'XXXXXX', 'dev_id': 'XXXX', 'hardware_serial': 'XXXX', 'port': 6, 'counter': 4289, 'payload_raw': 'XXXXX', 'payload_fields': {'aamsg_type': 'weather', 'abstatus': 0, 'batteryV': 3.5, 'battery_low': 'no', 'humiP': 57.6, 'tempC': 16.9}, 'metadata': {'time': '2020-01-23T14:09:32.132070865Z', 'frequency': 867.3, 'modulation': 'LORA', 'data_rate': 'SF7BW125', 'airtime': 61696000, 'coding_rate': '4/5', 'gateways': [{'gtw_id': 'XXXXXX', 'timestamp': 3921981659, 'time': '2020-01-23T14:09:32.104672Z', 'channel': 4, 'rssi': -107, 'snr': 8.2, 'rf_chain': 0, 'latitude': 57.124737, 'longitude': -2.1646452, 'altitude': 90, 'location_source': 'registry'}]}}",
"created_at": "2020-01-23T14:09:32.448929Z",
"sensor": 1
}
}
I am getting the values till feed.我正在获取值直到饲料。 But I am not able to parse further, My code is :
但我无法进一步解析,我的代码是:
if(status_code == 200){
if let json = response.data {
do{
let data = try JSON(data: json)
let result = data["results"].arrayObject! as NSArray
let ct = result.count
if(ct != 0 ) {
self.noDataFound.isHidden = true
for i in 0...ct-1 {
let data = result[i] as? NSDictionary
let feed = data?.value(forKey: "feed") as? NSString
let data3 = try JSON(data: feed as! Data) .
print(data3)
}
}
} catch {} }}
I need to get the hardware_serial from feed.我需要从提要中获取hardware_serial。 Can any body please help me what i am doing wrong here!!
任何人都可以帮助我我在这里做错了什么!! Thanks!!!
谢谢!!!
feed
is not valid JSON.feed
的字符串不是有效的 JSON。 You have to replace the single quotes with double quotes.Data
object from the string (casting the type doesn't work).Data
对象(转换类型不起作用)。 Side note:边注:
Don't use NS...
collection types and NSString
in Swift.不要在 Swift 中使用
NS...
集合类型和NSString
。
Use Codable
to parse the above JSON response.使用
Codable
解析上述 JSON 响应。
Models:楷模:
struct Root: Codable {
let count: Int
let next: String
let previous: String?
let results: [Result]
}
struct Result: Codable {
let id: Int
let feed, createdAt: String
let sensor: Int
}
Parse the JSON data
like so,像这样解析JSON
data
,
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let response = try decoder.decode(Root.self, from: data)
print(response)
} catch {
print(error)
}
First, peel off the piece you want:首先,剥下你想要的那一块:
struct ResultWrapper: Decodable {
let results: [Result]
}
And then build a custom decoder to extract feed, which is malformed.然后构建自定义解码器来提取格式错误的提要。 Single-quotes are not legal JSON.
单引号不是合法的 JSON。 As a hack, the following code just substitutes all single-quotes with double-quotes, but this won't work if there are any embedded quoted-single-quotes.
作为一个黑客,以下代码只是用双引号替换了所有单引号,但是如果有任何嵌入的带引号的单引号,这将不起作用。
struct Result: Decodable {
enum CodingKeys: String, CodingKey { case feed }
let feed: Feed
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// inner JSON is mal-formed. Have to fix it.
let feedString = try container.decode(String.self, forKey: .feed)
.replacingOccurrences(of: "'", with: "\"")
feed = try JSONDecoder().decode(Feed.self, from: Data(feedString.utf8))
}
}
Finally, decoding Feed is mechanical, but requires custom CodingKeys.最后,解码 Feed 是机械的,但需要自定义 CodingKeys。 I recommend quicktype for that:
我推荐快速输入:
// https://app.quicktype.io?share=7O6iNJ3ugXb4mr84TIoG
struct Feed: Codable {
var appID, devID, hardwareSerial: String
var port, counter: Int
var payloadRaw: String
var payloadFields: PayloadFields
var metadata: Metadata
enum CodingKeys: String, CodingKey {
case appID = "app_id"
case devID = "dev_id"
case hardwareSerial = "hardware_serial"
case port, counter
case payloadRaw = "payload_raw"
case payloadFields = "payload_fields"
case metadata
}
}
// MARK: - Metadata
struct Metadata: Codable {
var time: String
var frequency: Double
var modulation, dataRate: String
var airtime: Int
var codingRate: String
var gateways: [Gateway]
enum CodingKeys: String, CodingKey {
case time, frequency, modulation
case dataRate = "data_rate"
case airtime
case codingRate = "coding_rate"
case gateways
}
}
// MARK: - Gateway
struct Gateway: Codable {
var gtwID: String
var timestamp: Int
var time: String
var channel, rssi: Int
var snr: Double
var rfChain: Int
var latitude, longitude: Double
var altitude: Int
var locationSource: String
enum CodingKeys: String, CodingKey {
case gtwID = "gtw_id"
case timestamp, time, channel, rssi, snr
case rfChain = "rf_chain"
case latitude, longitude, altitude
case locationSource = "location_source"
}
}
// MARK: - PayloadFields
struct PayloadFields: Codable {
var aamsgType: String
var abstatus: Int
var batteryV: Double
var batteryLow: String
var humiP, tempC: Double
enum CodingKeys: String, CodingKey {
case aamsgType = "aamsg_type"
case abstatus, batteryV
case batteryLow = "battery_low"
case humiP, tempC
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.