swift - json swift4 how to set the struct? -
i want parse json http resource (it's router http mandatory).
after set info.plist
app security transport
connection data 1st attempted:
let sphdataaddress = "http://speedport.ip/data/status.json" let url = url(string: sphdataaddress)! let jsondata = try! data(contentsof: url) // ! testing reason , in real app guard let print("data \(jsondata)") // shows received data 5077bytes struct user { let vartype: string let varid: string let varvalue: company init?(dict: [string: any]) { guard let vartype = dict["vartype-data"] as? string, let varid = dict["valid-data"] as? string, let varvaluedict = dict["company"] as? [string: any], let varvalue = company(dict: varvaluedict) else { return nil } self.vartype = vartype self.varid = varid self.varvalue = varvalue } struct company { let vartype: string let varid: string let varvalue: string init?(dict: [string: any]) { guard let vartype = dict["vartype-sub"] as? string, let varid = dict["varid-sub"] as? string, let varvalue = dict["varvalue-sub"] as? string else { return nil } self.vartype = vartype self.varid = varid self.varvalue = varvalue } } } if let json = try? jsonserialization.jsonobject(with: jsondata, options: []) { if let jsonarray = json as? [[string: any]] { let users = jsonarray.flatmap { $0.map { $0} } let zun = users.count print(users, zun) } }
2nd attempt: ve tried 1 without success: // put viewed load test it!!
struct routerdata: decodable { let vartype: string? let varid: string? let varvalue: string? } override func viewdidload() { super.viewdidload() let jsonurlstring = "http://speedport.ip/data/status.json" guard let url = url(string: jsonurlstring) else { return } urlsession.shared.datatask(with: url) { (data, response, err) in //perhaps check err checked print(response) //also perhaps check response status 200 ok guard let data = data else { return } { let courses = try jsondecoder().decode([routerdata].self, from: data) print(courses) } catch let jsonerr { print("error serializing json:", jsonerr) } }.resume()
}
the error in console: typemismatch(swift.string, swift.decodingerror.context(codingpath: [foundation.(_jsonkey in _12768ca107a31ef2dce034fd75b541c9)(stringvalue: "index 25", intvalue: optional(25)), jsonparseswift4.routerdata.(codingkeys in _dd16afbb8a755d282dc27e60a66fdc03).varvalue], debugdescription: "expected decode string found array instead.", underlyingerror: nil)) thats (full) json structure comming source (router)
( { varid = "device_name"; vartype = value; varvalue = "speedport hybrid"; }, { varid = "provis_inet"; vartype = value; varvalue = x03; }, { varid = "provis_voip"; vartype = value; varvalue = xx3; }, { varid = "ppp_bnguser"; vartype = value; varvalue = 0; }, { varid = bngscrat; vartype = value; varvalue = 0; }, { varid = "router_state"; vartype = value; varvalue = ok; }, { varid = "support_https"; vartype = value; varvalue = 0; }, { varid = title; vartype = "page_title"; varvalue = "speedport hybrid konfigurationsprogramm"; }, { varid = onlinestatus; vartype = status; varvalue = online; }, { varid = "use_lte"; vartype = option; varvalue = 1; }, { varid = "lte_status"; vartype = value; varvalue = 10; }, { varid = "bonding_status"; vartype = value; varvalue = online; }, { varid = "lte_signal"; vartype = value; varvalue = 5; }, { varid = loginstate; vartype = status; varvalue = 0; }, { varid = datetime; vartype = value; varvalue = "18.08.2017 14:54:30"; }, { varid = "device_name"; vartype = value; varvalue = "speedport hybrid"; }, { varid = imei; vartype = value; varvalue = 1234567891230; }, { varid = "dsl_link_status"; vartype = value; varvalue = online; }, { varid = "dsl_errnr"; vartype = value; varvalue = ""; }, { varid = status; vartype = value; varvalue = online; }, { varid = "fail_reason"; vartype = value; varvalue = ""; }, { varid = "inet_errnr"; vartype = value; varvalue = ""; }, { varid = connect; vartype = value; varvalue = 0; }, { varid = "dsl_downstream"; vartype = value; varvalue = 8184; }, { varid = "dsl_upstream"; vartype = value; varvalue = 2429; }, { varid = addphonenumber; vartype = template; varvalue = ( { varid = id; vartype = value; varvalue = 1; }, { varid = "phone_number"; vartype = value; varvalue = „*100“; }, { varid = failreason; vartype = value; varvalue = 0; }, { varid = status; vartype = value; varvalue = ok; }, { varid = "voip_errnr"; vartype = value; varvalue = ""; } ); }, { varid = addphonenumber; vartype = template; varvalue = ( { varid = id; vartype = value; varvalue = 2; }, { varid = "phone_number"; vartype = value; varvalue = „*200"; }, { varid = failreason; vartype = value; varvalue = 0; }, { varid = status; vartype = value; varvalue = ok; }, { varid = "voip_errnr"; vartype = value; varvalue = ""; } ); }, { varid = addphonenumber; vartype = template; varvalue = ( { varid = id; vartype = value; varvalue = 3; }, { varid = "phone_number"; vartype = value; varvalue = „*300“; }, { varid = failreason; vartype = value; varvalue = 0; }, { varid = status; vartype = value; varvalue = ok; }, { varid = "voip_errnr"; vartype = value; varvalue = ""; } ); }, { varid = adddect; vartype = template; varvalue = ( { varid = id; vartype = value; varvalue = 1; } ); }, { varid = adddect; vartype = template; varvalue = ( { varid = id; vartype = value; varvalue = 2; } ); }, { varid = adddect; vartype = template; varvalue = ( { varid = id; vartype = value; varvalue = 3; } ); }, { varid = "use_dect"; vartype = value; varvalue = 1; }, { varid = "wlan_ssid"; vartype = value; varvalue = speedport; }, { varid = "wlan_5ghz_ssid"; vartype = value; varvalue = speedport5; }, { varid = "use_wlan"; vartype = value; varvalue = 1; }, { varid = "use_wlan_5ghz"; vartype = value; varvalue = 1; }, { varid = "wlan_devices"; vartype = value; varvalue = 0; }, { varid = "wlan_5ghz_devices"; vartype = value; varvalue = 3; }, { varid = "lan1_device"; vartype = value; varvalue = 1; }, { varid = "lan2_device"; vartype = value; varvalue = 1; }, { varid = "lan3_device"; vartype = value; varvalue = 1; }, { varid = "lan4_device"; vartype = value; varvalue = 1; }, { varid = "use_wps"; vartype = value; varvalue = 1; }, { varid = "hsfon_status"; vartype = value; varvalue = 0; }, { varid = "firmware_version"; vartype = value; varvalue = "050124.03.05.017"; }, { varid = "serial_number"; vartype = value; varvalue = sp123456789; })
the data comming router are:
the json snipped want show varvalue
once string , once []
sub data same var
's.
assuming json structure intended paste:
[ { "varid": "dsl_downstream", "vartype": "value", "varvalue": 11111 }, { "varid": "adddect", "vartype": "template", "varvalue": [ { "varid": "id", "vartype": "value", "varvalue": "some_value" } ] } ]
here's possible solution:
// let jsondata = "...".data(using: .utf8)! enum either<a,b> a: decodable, b: decodable { case left(a) case right(b) } struct routerdata: decodable { let type: string let id: string let value: either<string,[routerdata]> enum codingkeys: string, codingkey { case type = "vartype" case id = "varid" case value = "varvalue" } init(from decoder: decoder) throws { let container = try decoder.container(keyedby: codingkeys.self) type = try container.decode(string.self, forkey: .type) id = try container.decode(string.self, forkey: .id) if let elementvalue = try? container.decode(string.self, forkey: .value) { value = .left(elementvalue) } else if let elementvalue = try? container.decode(int.self, forkey: .value) { value = .left(string(elementvalue)) } else { let childdata = try container.decode([routerdata].self, forkey: .value) value = .right(childdata) } } } let decoded = try jsondecoder().decode([routerdata].self, from: jsondata) print(decoded)
Comments
Post a Comment