Related
I'm building a simple app which fetches json data from server and present it to user.I have a json file in vapor Public directory and when I try to parse it in iOS app it gives an error data is in incorrect format.I have converted the json file to swift struct by using json to swift online convertor.
But when I test the server response with postman it gives me the json file.In iOS app it gives me an error.I was able to fetch the data if I print it it gives 1372 bytes but when I try to parse it gives me an error that data is incorrect format
I'm getting following error
typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))
my json file
{
"memes": [
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-53-300x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-53.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-1-300x210.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-1.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-54-300x250.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-54.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-55-300x269.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-55.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-56.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-56.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-57.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-57.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-58.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-58.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-8.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-8.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-59.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-59.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-66.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-66.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/download.jpg",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/download.jpg"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-12-300x281.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-12.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-13-300x281.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-13.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-14-240x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-14.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-61.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-61.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-62.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-62.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-17-300x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-17.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-18-252x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-18.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-19-300x281.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-19.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-20-249x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-20.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-21-300x233.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-21.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-63.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-63.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-64.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-64.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-24-300x150.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-24.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-25-289x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-25.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-27.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-27.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-52-300x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-52.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-30-300x221.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-30.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-65.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-65.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-32-300x239.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-32.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-33-300x181.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-33.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-34-300x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-34.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-35-300x250.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-35.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-36-300x269.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-36.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-37-300x210.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-37.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-38-300x292.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-38.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-39-300x167.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-39.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-40-249x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-40.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-41-300x294.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-41.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-42-300x295.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-42.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-43-234x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-43.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-44-300x263.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-44.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-45-300x255.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-45.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-46-300x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-46.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-47.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-47.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-48-300x210.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-48.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-49-249x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-49.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-50-300x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-50.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-51-300x146.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-51.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/05/python-2.jpg",
"url": "https://www.probytes.net/python-development-company/"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/1.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/1.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/2.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/2.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/3.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/3.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/4-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/4-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/5-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/5-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/6-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/6-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/7-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/7-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/8-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/8-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/9-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/9-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/10-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/10-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/11-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/11-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/12-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/12-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/13-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/13-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/14-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/14-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/15-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/15-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/16.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/16.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/17.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/17.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/18.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/18.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/19.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/19.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/20.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/20.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/9-1.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/9-1.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/8-1.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/8-1.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/7.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/7.jpg"
},
{
"image": "https://s.w.org/images/core/emoji/12.0.0-1/svg/1f609.svg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/3-2.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/3-2.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/6-1.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/6-1.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/Imgur-8801b2-1.png",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/Imgur-8801b2-1.png"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/5-1.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/5-1.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/r_389776_tqMPa-1.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/r_389776_tqMPa-1.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/2-2.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/2-2.jpg"
},
{
"image": "https://www.probytes.net/wp-content/uploads/2018/01/4.jpg",
"url": "https://www.probytes.net/wp-content/uploads/2018/01/4.jpg"
}
]
}
Routes.swift file in Vapor
import Vapor
struct Welcome: Codable,Content {
let memes: [Meme]
}
struct Meme: Codable,Content {
let image: String
let url: String?
}
func routes(_ app: Application) throws {
var m = [Meme]()
var path = app.directory.publicDirectory
path.append("memes.json")
print(path)
guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else {return }
do
{
let memess = try JSONDecoder().decode(Welcome.self, from: data)
m = memess.memes
}
catch{
print(error.localizedDescription)
}
app.get { req in
return m
}
}
iOS App codable struct file
import Foundation
public struct Json4Swift_Base : Codable {
public let memes : [Memes]?
public enum CodingKeys: String, CodingKey {
case memes = "memes"
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
memes = try values.decodeIfPresent([Memes].self, forKey: .memes)
}
}
public struct Memes : Codable {
public let image : String?
public let url : String?
public enum CodingKeys: String, CodingKey {
case image = "image"
case url = "url"
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
image = try values.decodeIfPresent(String.self, forKey: .image)
url = try values.decodeIfPresent(String.self, forKey: .url)
}
}
NetworkService file
import Foundation
public class NetworkService
{
public static let sharedobj = NetworkService()
public let url = URL(string:"http://127.0.0.1:8080")
public let session = URLSession(configuration: .default)
public func getMemes(onSucces:#escaping([Memes],Error?)->Void)
{
let task = session.dataTask(with: url!) { (data, response, error) in
do
{
let items = try JSONDecoder().decode(Json4Swift_Base.self, from: data!)
onSucces(items.memes!,error)
}
catch
{
print(error.localizedDescription)
}
}
task.resume()
}
}
In your Vapor code you decode the file and then extract only the array to a property so assuming that this is what you encode and send to the client then you only receive the array.
Like this
"[
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-53-300x300.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-53.png"
},
{
"image": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-1-300x210.png",
"url": "https://www.testbytes.net/wp-content/uploads/2019/06/Untitled-1.png"
},
...
]"
So in your client you should decode the array only
let items = try JSONDecoder().decode([Memes].self, from: data!)
And you don't need init(from:) or a CodingKey enum here.
I used Json4Swift web site.
Root Model:
struct Json4Swift_Base : Codable {
let trends : [Trends]?
let as_of : String?
let created_at : String?
let locations : [Locations]?
enum CodingKeys: String, CodingKey {
case trends = "trends"
case as_of = "as_of"
case created_at = "created_at"
case locations = "locations"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
trends = try values.decodeIfPresent([Trends].self, forKey: .trends)
as_of = try values.decodeIfPresent(String.self, forKey: .as_of)
created_at = try values.decodeIfPresent(String.self, forKey: .created_at)
locations = try values.decodeIfPresent([Locations].self, forKey: .locations)
}
}
Location Model:
struct Locations : Codable {
let name : String?
let woeid : Int?
enum CodingKeys: String, CodingKey {
case name = "name"
case woeid = "woeid"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
woeid = try values.decodeIfPresent(Int.self, forKey: .woeid)
}
}
Trend Model:
struct Trends : Codable {
let name : String?
let url : String?
let promoted_content : String?
let query : String?
let tweet_volume : Int?
enum CodingKeys: String, CodingKey {
case name = "name"
case url = "url"
case promoted_content = "promoted_content"
case query = "query"
case tweet_volume = "tweet_volume"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
url = try values.decodeIfPresent(String.self, forKey: .url)
promoted_content = try values.decodeIfPresent(String.self, forKey: .promoted_content)
query = try values.decodeIfPresent(String.self, forKey: .query)
tweet_volume = try values.decodeIfPresent(Int.self, forKey: .tweet_volume)
}
}
Twitter Request Code:
let request = client.urlRequest(withMethod: "GET", urlString: statusesShowEndpoint, parameters: params, error: &clientError)
client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
if connectionError != nil {
print("Error: \(String(describing: connectionError))")
}
do {
// let json = try JSONSerialization.jsonObject(with: data!, options: [])
// print(json)
// -> How do I get the data without using this code.
let rssFeed = try JSONDecoder().decode(Json4Swift_Base.self, from: data!)
self.trends = rssFeed.trends!
} catch let jsonError as NSError {
print("json error: \(jsonError.localizedDescription)")
}
}
print("Trend: \(trends)")
}
}
How can I get Tweet with JSONDecoder().decode()
how do I get the data without using this code. JSONSerialization.jsonObject()
I get an error when I use this code.
let rssFeed = try JSONDecoder().decode(Json4Swift_Base.self, from: data!)
Twitter Api is here: https://developer.twitter.com/en/docs/trends/trends-for-location/api-reference/get-trends-place
How can I decode JSON Data. Sorry for my English. I know little English.
JSON
So this is your JSON
let data = """
[
{
"trends": [
{
"name": "#ChainedToTheRhythm",
"url": "http://twitter.com/search?q=%23ChainedToTheRhythm",
"promoted_content": null,
"query": "%23ChainedToTheRhythm",
"tweet_volume": 48857
},
{
"name": "#اليوم_العالمي_للعتبان",
"url": "http://twitter.com/search?q=%23%D8%A7%D9%84%D9%8A%D9%88%D9%85_%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85%D9%8A_%D9%84%D9%84%D8%B9%D8%AA%D8%A8%D8%A7%D9%86",
"promoted_content": null,
"query": "%23%D8%A7%D9%84%D9%8A%D9%88%D9%85_%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85%D9%8A_%D9%84%D9%84%D8%B9%D8%AA%D8%A8%D8%A7%D9%86",
"tweet_volume": null
},
{
"name": "George Lopez",
"url": "http://twitter.com/search?q=%22George+Lopez%22",
"promoted_content": null,
"query": "%22George+Lopez%22",
"tweet_volume": 90590
},
{
"name": "#قل_كلمه_للي_يتابعك",
"url": "http://twitter.com/search?q=%23%D9%82%D9%84_%D9%83%D9%84%D9%85%D9%87_%D9%84%D9%84%D9%8A_%D9%8A%D8%AA%D8%A7%D8%A8%D8%B9%D9%83",
"promoted_content": null,
"query": "%23%D9%82%D9%84_%D9%83%D9%84%D9%85%D9%87_%D9%84%D9%84%D9%8A_%D9%8A%D8%AA%D8%A7%D8%A8%D8%B9%D9%83",
"tweet_volume": null
},
{
"name": "#FelizMiercoles",
"url": "http://twitter.com/search?q=%23FelizMiercoles",
"promoted_content": null,
"query": "%23FelizMiercoles",
"tweet_volume": 36103
},
{
"name": "#wednesdaywisdom",
"url": "http://twitter.com/search?q=%23wednesdaywisdom",
"promoted_content": null,
"query": "%23wednesdaywisdom",
"tweet_volume": 42916
},
{
"name": "Tara Palmer-Tomkinson",
"url": "http://twitter.com/search?q=%22Tara+Palmer-Tomkinson%22",
"promoted_content": null,
"query": "%22Tara+Palmer-Tomkinson%22",
"tweet_volume": null
},
{
"name": "呪いチョコ",
"url": "http://twitter.com/search?q=%E5%91%AA%E3%81%84%E3%83%81%E3%83%A7%E3%82%B3",
"promoted_content": null,
"query": "%E5%91%AA%E3%81%84%E3%83%81%E3%83%A7%E3%82%B3",
"tweet_volume": 15704
},
{
"name": "メンテ",
"url": "http://twitter.com/search?q=%E3%83%A1%E3%83%B3%E3%83%86",
"promoted_content": null,
"query": "%E3%83%A1%E3%83%B3%E3%83%86",
"tweet_volume": 344416
},
{
"name": "SLAY CAMILIZERS",
"url": "http://twitter.com/search?q=%22SLAY+CAMILIZERS%22",
"promoted_content": null,
"query": "%22SLAY+CAMILIZERS%22",
"tweet_volume": 707166
},
{
"name": "あなたの精神年齢",
"url": "http://twitter.com/search?q=%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E7%B2%BE%E7%A5%9E%E5%B9%B4%E9%BD%A2",
"promoted_content": null,
"query": "%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E7%B2%BE%E7%A5%9E%E5%B9%B4%E9%BD%A2",
"tweet_volume": null
},
{
"name": "WORK FROM 5H",
"url": "http://twitter.com/search?q=%22WORK+FROM+5H%22",
"promoted_content": null,
"query": "%22WORK+FROM+5H%22",
"tweet_volume": 54061
},
{
"name": "Leyla Zana",
"url": "http://twitter.com/search?q=%22Leyla+Zana%22",
"promoted_content": null,
"query": "%22Leyla+Zana%22",
"tweet_volume": null
},
{
"name": "#TwoJustin",
"url": "http://twitter.com/search?q=%23TwoJustin",
"promoted_content": null,
"query": "%23TwoJustin",
"tweet_volume": null
},
{
"name": "#MyFirstAndLast",
"url": "http://twitter.com/search?q=%23MyFirstAndLast",
"promoted_content": null,
"query": "%23MyFirstAndLast",
"tweet_volume": 63844
},
{
"name": "#ValentinesDayIn3Words",
"url": "http://twitter.com/search?q=%23ValentinesDayIn3Words",
"promoted_content": null,
"query": "%23ValentinesDayIn3Words",
"tweet_volume": null
},
{
"name": "#ShePersisted",
"url": "http://twitter.com/search?q=%23ShePersisted",
"promoted_content": null,
"query": "%23ShePersisted",
"tweet_volume": 45624
},
{
"name": "#HappyJohnnyDay",
"url": "http://twitter.com/search?q=%23HappyJohnnyDay",
"promoted_content": null,
"query": "%23HappyJohnnyDay",
"tweet_volume": 28560
},
{
"name": "#QuartaDetremuraSDV",
"url": "http://twitter.com/search?q=%23QuartaDetremuraSDV",
"promoted_content": null,
"query": "%23QuartaDetremuraSDV",
"tweet_volume": 10481
},
{
"name": "#ترحيل_الاجانب_مطلب_وطني",
"url": "http://twitter.com/search?q=%23%D8%AA%D8%B1%D8%AD%D9%8A%D9%84_%D8%A7%D9%84%D8%A7%D8%AC%D8%A7%D9%86%D8%A8_%D9%85%D8%B7%D9%84%D8%A8_%D9%88%D8%B7%D9%86%D9%8A",
"promoted_content": null,
"query": "%23%D8%AA%D8%B1%D8%AD%D9%8A%D9%84_%D8%A7%D9%84%D8%A7%D8%AC%D8%A7%D9%86%D8%A8_%D9%85%D8%B7%D9%84%D8%A8_%D9%88%D8%B7%D9%86%D9%8A",
"tweet_volume": null
},
{
"name": "#TapperDirtFile",
"url": "http://twitter.com/search?q=%23TapperDirtFile",
"promoted_content": null,
"query": "%23TapperDirtFile",
"tweet_volume": null
},
{
"name": "#FelizCumplePresidente",
"url": "http://twitter.com/search?q=%23FelizCumplePresidente",
"promoted_content": null,
"query": "%23FelizCumplePresidente",
"tweet_volume": 15276
},
{
"name": "#MeCasoSiMeDices",
"url": "http://twitter.com/search?q=%23MeCasoSiMeDices",
"promoted_content": null,
"query": "%23MeCasoSiMeDices",
"tweet_volume": null
},
{
"name": "#FebreroZamorista",
"url": "http://twitter.com/search?q=%23FebreroZamorista",
"promoted_content": null,
"query": "%23FebreroZamorista",
"tweet_volume": null
},
{
"name": "#NãoSuportoQuando",
"url": "http://twitter.com/search?q=%23N%C3%A3oSuportoQuando",
"promoted_content": null,
"query": "%23N%C3%A3oSuportoQuando",
"tweet_volume": 14327
},
{
"name": "#NinguemSabeMasEuJa",
"url": "http://twitter.com/search?q=%23NinguemSabeMasEuJa",
"promoted_content": null,
"query": "%23NinguemSabeMasEuJa",
"tweet_volume": 12856
},
{
"name": "#وش_شعورك_اول_يوم_دوام",
"url": "http://twitter.com/search?q=%23%D9%88%D8%B4_%D8%B4%D8%B9%D9%88%D8%B1%D9%83_%D8%A7%D9%88%D9%84_%D9%8A%D9%88%D9%85_%D8%AF%D9%88%D8%A7%D9%85",
"promoted_content": null,
"query": "%23%D9%88%D8%B4_%D8%B4%D8%B9%D9%88%D8%B1%D9%83_%D8%A7%D9%88%D9%84_%D9%8A%D9%88%D9%85_%D8%AF%D9%88%D8%A7%D9%85",
"tweet_volume": null
},
{
"name": "#HappyChunghaDay",
"url": "http://twitter.com/search?q=%23HappyChunghaDay",
"promoted_content": null,
"query": "%23HappyChunghaDay",
"tweet_volume": 16480
},
{
"name": "#DiaDeLaPiscola",
"url": "http://twitter.com/search?q=%23DiaDeLaPiscola",
"promoted_content": null,
"query": "%23DiaDeLaPiscola",
"tweet_volume": null
},
{
"name": "#زواج_الامير_بدر_بن_عبدالله",
"url": "http://twitter.com/search?q=%23%D8%B2%D9%88%D8%A7%D8%AC_%D8%A7%D9%84%D8%A7%D9%85%D9%8A%D8%B1_%D8%A8%D8%AF%D8%B1_%D8%A8%D9%86_%D8%B9%D8%A8%D8%AF%D8%A7%D9%84%D9%84%D9%87",
"promoted_content": null,
"query": "%23%D8%B2%D9%88%D8%A7%D8%AC_%D8%A7%D9%84%D8%A7%D9%85%D9%8A%D8%B1_%D8%A8%D8%AF%D8%B1_%D8%A8%D9%86_%D8%B9%D8%A8%D8%AF%D8%A7%D9%84%D9%84%D9%87",
"tweet_volume": null
},
{
"name": "#UnBuenTaco",
"url": "http://twitter.com/search?q=%23UnBuenTaco",
"promoted_content": null,
"query": "%23UnBuenTaco",
"tweet_volume": null
},
{
"name": "#PMQs",
"url": "http://twitter.com/search?q=%23PMQs",
"promoted_content": null,
"query": "%23PMQs",
"tweet_volume": 20406
},
{
"name": "#InteractFalando",
"url": "http://twitter.com/search?q=%23InteractFalando",
"promoted_content": null,
"query": "%23InteractFalando",
"tweet_volume": null
},
{
"name": "#ナカイの窓",
"url": "http://twitter.com/search?q=%23%E3%83%8A%E3%82%AB%E3%82%A4%E3%81%AE%E7%AA%93",
"promoted_content": null,
"query": "%23%E3%83%8A%E3%82%AB%E3%82%A4%E3%81%AE%E7%AA%93",
"tweet_volume": 14835
},
{
"name": "#حزب_اللي_ما_يحبون_دانكن",
"url": "http://twitter.com/search?q=%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D9%84%D9%8A_%D9%85%D8%A7_%D9%8A%D8%AD%D8%A8%D9%88%D9%86_%D8%AF%D8%A7%D9%86%D9%83%D9%86",
"promoted_content": null,
"query": "%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D9%84%D9%8A_%D9%85%D8%A7_%D9%8A%D8%AD%D8%A8%D9%88%D9%86_%D8%AF%D8%A7%D9%86%D9%83%D9%86",
"tweet_volume": 18170
},
{
"name": "#LIZAonTWBA",
"url": "http://twitter.com/search?q=%23LIZAonTWBA",
"promoted_content": null,
"query": "%23LIZAonTWBA",
"tweet_volume": 68066
},
{
"name": "#nldebat",
"url": "http://twitter.com/search?q=%23nldebat",
"promoted_content": null,
"query": "%23nldebat",
"tweet_volume": null
},
{
"name": "#ConselhosDeUmTrouxa",
"url": "http://twitter.com/search?q=%23ConselhosDeUmTrouxa",
"promoted_content": null,
"query": "%23ConselhosDeUmTrouxa",
"tweet_volume": 11419
},
{
"name": "#PBBKiligOverload",
"url": "http://twitter.com/search?q=%23PBBKiligOverload",
"promoted_content": null,
"query": "%23PBBKiligOverload",
"tweet_volume": 70766
},
{
"name": "#MiMejorPiropoParaTi",
"url": "http://twitter.com/search?q=%23MiMejorPiropoParaTi",
"promoted_content": null,
"query": "%23MiMejorPiropoParaTi",
"tweet_volume": null
},
{
"name": "#8Feb",
"url": "http://twitter.com/search?q=%238Feb",
"promoted_content": null,
"query": "%238Feb",
"tweet_volume": null
},
{
"name": "#عوده_منصور_البلوي",
"url": "http://twitter.com/search?q=%23%D8%B9%D9%88%D8%AF%D9%87_%D9%85%D9%86%D8%B5%D9%88%D8%B1_%D8%A7%D9%84%D8%A8%D9%84%D9%88%D9%8A",
"promoted_content": null,
"query": "%23%D8%B9%D9%88%D8%AF%D9%87_%D9%85%D9%86%D8%B5%D9%88%D8%B1_%D8%A7%D9%84%D8%A8%D9%84%D9%88%D9%8A",
"tweet_volume": null
},
{
"name": "#LoveBeyondFlags",
"url": "http://twitter.com/search?q=%23LoveBeyondFlags",
"promoted_content": null,
"query": "%23LoveBeyondFlags",
"tweet_volume": null
},
{
"name": "#EscándaloOdebrecht",
"url": "http://twitter.com/search?q=%23Esc%C3%A1ndaloOdebrecht",
"promoted_content": null,
"query": "%23Esc%C3%A1ndaloOdebrecht",
"tweet_volume": null
},
{
"name": "#PregúntaleAPedro",
"url": "http://twitter.com/search?q=%23Preg%C3%BAntaleAPedro",
"promoted_content": null,
"query": "%23Preg%C3%BAntaleAPedro",
"tweet_volume": null
},
{
"name": "#بذاءه_مصري_في_كريم",
"url": "http://twitter.com/search?q=%23%D8%A8%D8%B0%D8%A7%D8%A1%D9%87_%D9%85%D8%B5%D8%B1%D9%8A_%D9%81%D9%8A_%D9%83%D8%B1%D9%8A%D9%85",
"promoted_content": null,
"query": "%23%D8%A8%D8%B0%D8%A7%D8%A1%D9%87_%D9%85%D8%B5%D8%B1%D9%8A_%D9%81%D9%8A_%D9%83%D8%B1%D9%8A%D9%85",
"tweet_volume": 38019
},
{
"name": "#MSWL",
"url": "http://twitter.com/search?q=%23MSWL",
"promoted_content": null,
"query": "%23MSWL",
"tweet_volume": null
},
{
"name": "#WhatsappÇöktü",
"url": "http://twitter.com/search?q=%23Whatsapp%C3%87%C3%B6kt%C3%BC",
"promoted_content": null,
"query": "%23Whatsapp%C3%87%C3%B6kt%C3%BC",
"tweet_volume": null
},
{
"name": "#SoMeArrependoDe",
"url": "http://twitter.com/search?q=%23SoMeArrependoDe",
"promoted_content": null,
"query": "%23SoMeArrependoDe",
"tweet_volume": null
},
{
"name": "#حزب_العاطلين_بتويتر",
"url": "http://twitter.com/search?q=%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D8%B9%D8%A7%D8%B7%D9%84%D9%8A%D9%86_%D8%A8%D8%AA%D9%88%D9%8A%D8%AA%D8%B1",
"promoted_content": null,
"query": "%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D8%B9%D8%A7%D8%B7%D9%84%D9%8A%D9%86_%D8%A8%D8%AA%D9%88%D9%8A%D8%AA%D8%B1",
"tweet_volume": null
}
],
"as_of": "2017-02-08T16:18:18Z",
"created_at": "2017-02-08T16:10:33Z",
"locations": [
{
"name": "Worldwide",
"woeid": 1
}
]
}
]
""".data(using: .utf8)!
Model
Now you can simplify your model
struct Location: Codable {
let name: String?
let woeid: Int?
}
struct Trend: Codable {
let name: String?
let url: URL?
let promotedContent: String?
let query: String?
let tweetVolume: Int?
}
struct Element: Codable {
let trends: [Trend]?
let asOf: String?
let createdAt: String?
let locations: [Location]?
}
Decoding from snake_case_notation
Next you can created your JSONDecoder() and properly set the key decoding strategy.
let jsonDecoder = JSONDecoder()
jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
Decoding!!
And finally remember that your JSON is an array of elements, so during the decoding use [Element].self instead if Element.self.
do {
let response = try JSONDecoder().decode([Element].self, from: data)
print(response)
} catch {
print(error)
}
That's it.
UPDATE
About your comment
How can get trends from Elements array ?
This is how you access the Trend values.
do {
let response = try JSONDecoder().decode([Element].self, from: data)
for element in response {
for trend in element.trends ?? [] {
print(trend)
}
}
} catch {
print(error)
}
You can also save all the Trend(s) into a single array
let allTrends = response.compactMap { $0.trends }.flatMap { $0 }
print(allTrends)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to get data from Json and put it in the table and display it from the API via Alamofire through the 'Post' process that has parameters containing the page number
I want get "results" ..
{
"responseCode": 200,
"message": null,
"status": true,
"results": [
{
"id": 971,
"title": "ST201972362",
"cdate": "07/31/2019",
"summary": "test",
"address": "",
"timer": "77876203",
"lat": "31.515934",
"lng": "34.4494066",
"source": "2",
"CreatedOn": "2019-07-31T13:38:46.927",
"done_940": null
},
{
"id": 970,
"title": "ST201972356",
"cdate": "07/30/2019",
"summary": "ov",
"address": "",
"timer": "0",
"lat": "31.5159315",
"lng": "34.4493925",
"source": "2",
"CreatedOn": "2019-07-30T15:26:00.077",
"done_940": null
},
{
"id": 964,
"title": "ST201972341",
"cdate": "07/29/2019",
"summary": "تجربة بلاغ ",
"address": "",
"timer": "0",
"lat": "21.5066086",
"lng": "39.1758587",
"source": "2",
"CreatedOn": "2019-07-29T19:06:58.817",
"done_940": null
},
{
"id": 959,
"title": "ST201972820252314",
"cdate": "07/28/2019",
"summary": "اااااا",
"address": "",
"timer": "0",
"lat": "21.5066716",
"lng": "39.1758483",
"source": "1",
"CreatedOn": "2019-07-28T11:45:02.493",
"done_940": null
},
{
"id": 957,
"title": "ST201972312",
"cdate": "07/28/2019",
"summary": "تمتمتم",
"address": "",
"timer": "0",
"lat": "31.5397884",
"lng": "34.4544891",
"source": "2",
"CreatedOn": "2019-07-28T08:56:43.577",
"done_940": null
},
{
"id": 956,
"title": "ST201972312",
"cdate": "07/28/2019",
"summary": "لا تنام",
"address": "",
"timer": "0",
"lat": "31.5397238",
"lng": "34.4540829",
"source": "2",
"CreatedOn": "2019-07-28T08:56:00.15",
"done_940": null
},
{
"id": 955,
"title": "ST201972311",
"cdate": "07/28/2019",
"summary": "تجربه جديد",
"address": "",
"timer": "0",
"lat": "31.5395001",
"lng": "34.4542211",
"source": "2",
"CreatedOn": "2019-07-28T08:52:09.81",
"done_940": null
},
{
"id": 953,
"title": "ST201972309",
"cdate": "07/28/2019",
"summary": "يلا",
"address": "",
"timer": "0",
"lat": "31.5110196",
"lng": "34.4784933",
"source": "2",
"CreatedOn": "2019-07-28T05:30:29.647",
"done_940": null
},
{
"id": 952,
"title": "ST201972309",
"cdate": "07/28/2019",
"summary": "ماك ١",
"address": "",
"timer": "0",
"lat": "31.5110291",
"lng": "34.4785841",
"source": "2",
"CreatedOn": "2019-07-28T05:29:09.943",
"done_940": null
},
{
"id": 949,
"title": "ST201972307",
"cdate": "07/28/2019",
"summary": "مرحبا",
"address": "",
"timer": "0",
"lat": "31.5443154",
"lng": "34.4585304",
"source": "2",
"CreatedOn": "2019-07-28T00:20:42.753",
"done_940": null
}
],
"done_940": "2/811"
}
You can follow some steps:
Step 1: need to create model
struct ResultObject {
var responseCode: Int?
var message: String?
var status: Bool?
var result: [Result]
public init(response: [String: Any]) {
self.responseCode = response["responseCode"] as? Int
self.message = response["message"] as? String
self.status = response["status"] as? Bool
let results = response["result"] as! [[String: Any]]
self.result = []
for item in results {
let result = Result(result: item)
self.result.append(result)
}
}
struct Result {
var id: String?
var title: String?
var cdate: String?
var summary: String?
var address: String?
var timer: String?
var lat: String?
var lng: String?
var source: String?
var CreatedOn: String?
var done_940: String?
public init(result: [String: Any]) {
self.id = result["id"] as? String
self.title = result["title"] as? String
self.cdate = result["cdate"] as? String
self.summary = result["summary"] as? String
self.address = result["address"] as? String
self.timer = result["timer"] as? String
self.lat = result["lat"] as? String
self.lng = result["lng"] as? String
self.source = result["source"] as? String
self.CreatedOn = result["CreatedOn"] as? String
self.done_940 = result["done_940"] as? String
}
}
}
Step 2: You check response from Alamofile
if you get json then
let test = ResultObject(response: responseJson)
print(test)
incase you get response is type Response you must convert into json
let responseJSON = try? JSONSerialization.jsonObject(with: response.data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
let test = ResultObject(response: responseJSON)
print(test)
}
Let me know when you have some other problems.
Below is the code i tried to extract the JSON Object. I only want the Data with the status != Static and show that in tableView
postman response
[
{
"id": 249,
"name": "aBrush your teeth",
"desc": "Brush your teeth",
"reward": "1.00",
"sched": "2015-01-01T08:00:00+08:00",
"parent": "",
"type": "",
"child": "",
"occurrence": {
"name": "once"
},
"status": {
"name": "static"
},
"date_created": "2018-04-25T14:27:20.405928+08:00",
"date_modified": "2018-04-26T11:56:02.030647+08:00"
},
{
"id": 250,
"name": "Brush your teeth",
"desc": "Brush your teeth",
"reward": "1.00",
"sched": "2015-01-01T08:00:00+08:00",
"parent": "",
"type": "",
"child": "",
"occurrence": {
"name": "once"
},
"status": {
"name": "static"
},
"date_created": "2018-04-25T14:28:49.780354+08:00",
"date_modified": "2018-04-26T11:56:05.616333+08:00"
},
{
"id": 252,
"name": "Brush your teeth",
"desc": "Brush your teeth",
"reward": "1.00",
"sched": "2015-01-01T08:00:00+08:00",
"parent": "",
"type": "",
"child": "",
"occurrence": {
"name": "once"
},
"status": {
"name": "static"
},
"date_created": "2018-04-25T14:31:02.274405+08:00",
"date_modified": "2018-04-26T11:59:57.676148+08:00"
},
{
"id": 253,
"name": "Brush your teeth",
"desc": "Brush your teeth",
"reward": "1.00",
"sched": "2015-01-01T08:00:00+08:00",
"parent": "",
"type": "",
"child": "",
"occurrence": {
"name": "once"
},
"status": {
"name": "static"
},
"date_created": "2018-04-25T14:34:37.097498+08:00",
"date_modified": "2018-04-26T09:42:24.633359+08:00"
},
{
"id": 254,
"name": "Brush your teeth",
"desc": "Brush your teeths",
"reward": "1.00",
"sched": "2015-01-01T08:00:00+08:00",
"parent": "",
"type": "",
"child": "",
"occurrence": {
"name": "once"
},
"status": {
"name": "static"
},
"date_created": "2018-04-25T14:36:53.766088+08:00",
"date_modified": "2018-04-26T11:56:15.757769+08:00"
},
{
"id": 260,
"name": "chorename",
"desc": "{\n \"questions\" : [\n {\n \"b\" : 2,\n \"a\" : 1\n },\n {\n \"b\" : 3,\n \"a\" : 2\n },\n {\n \"b\" : 2,\n \"a\" : 8\n },\n {\n \"b\" : 9,\n \"a\" : 7\n },\n {\n \"b\" : 3,\n \"a\" : 6\n }\n ],\n \"operation\" : \"+\"\n}",
"reward": "1.00",
"sched": "2018-04-19T15:54:24.657644+08:00",
"parent": "shit",
"type": "homework",
"child": "",
"occurrence": {
"name": "once"
},
"status": {
"name": "ongoing"
},
"date_created": "2018-04-26T10:13:42.913149+08:00",
"date_modified": "2018-04-26T10:13:42.953485+08:00"
}
]
code in getting the data
// here i only want to get data from the dapi which status name != "static"
and append it to getalldetail which is an var getAllDetail: [[String:Any]] = [String:Any]
func demoApi() {
Alamofire.request("test.api", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
guard let json = response.result.value as! [[String:Any]]? else{ return}
print("Api Response : \(json)")
// here i only want to get data from the dapi which status name != "static"
for item in json {
self.getAllDetail.append(item)
}
if !self.getAllDetail.isEmpty{
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
break
case .failure(_):
print("Error")
break
}
}
}
Just apply filter to your response as like below.
let filtered = json.filter { (dict) -> Bool in
guard let status : [String : String] = dict["status"] as? [String : String], let statusString = status["name"] else {
return false
}
return statusString.compare("static") != .orderedSame
}
I recommend to take advantage of the Codable protocol of Swift 4 and decode the JSON into structs. This makes it very easy to filter the data. No type cast needed, no key subscription needed.
Create the structs
struct ResponseData : Decodable {
let id: Int
let name, desc, reward : String
let sched, parent, type, child : String
let occurrence : Status
let status : Status
let dateCreated, dateModified : String
}
struct Status : Decodable {
let name : String
}
Your data source array getAllDetail must be declared as
var getAllDetail = [ResponseData]()
In the Alamofire completion handler get the data and decode the JSON into the structs with JSONDecoder. The items can be filtered – pretty descriptively – with filter{ $0.status.name == "static" }
Alamofire.request("test.api", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
switch(response.result) {
case .success:
guard let data = response.data else { return }
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode([ResponseData].self, from: data)
self.getAllDetail = result.filter{ $0.status.name == "static" }
DispatchQueue.main.async {
self.tableView.reloadData()
}
case .failure(let error):
print("Error", error)
}
}
I'm trying to decode my json data with below function. I had different Json format at first and It was working but whenI change json format, It started not to work. 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)
First 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:
{
"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. 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
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. You can catch decoding related issues quickly by implementing proper catch blocks. E.g.:
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.