Swift.DecodingError.Context - swift

i am decoding JSON (Decoder) string from URL repsonse as follows and get a get during the decoding process the following error messages:
Error:
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "tags", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "Expected to decode String but found a number instead.", underlyingError: nil))
Structure:
struct Wordpress: Codable {
let id: Int?
let date: String?
let date_gmt: String?
let guid: GUID?
let modified: String?
let modified_gmt: String?
let slug: String?
let status: String?
let type: String?
let link: String?
let title: Title?
let content: Content?
let excerpt: Excerpt?
let author: Int?
let featured_media: Int?
let comment_status: String?
let ping_status: String?
let sticky: Bool?
let template: String?
let format: String?
let meta: [String]?
let categories: [Int]?
let tags: [String]?
let _links: Link?
enum CodingKeys: String, CodingKey {
case id = "id"
case date = "date"
case date_gmt = "date_gmt"
case guid = "guid"
case modified = "modified"
case modified_gmt = "modified_gmt"
case slug = "slug"
case status = "status"
case type = "type"
case link = "link"
case title = "title"
case content = "content"
case excerpt = "excerpt"
case author = "author"
case featured_media = "featured_media"
case comment_status = "comment_status"
case ping_status = "ping_status"
case sticky = "sticky"
case template = "template"
case format = "format"
case meta = "meta"
case categories = "categories"
case tags = "tags"
case _links = "_links"
}
}
struct GUID: Codable{
let rendered: String?
}
struct Title: Codable{
let rendered: String?
}
struct Content: Codable{
let rendered: String?
let protected: Bool?
}
struct Excerpt: Codable{
let rendered: String?
let protected: Bool?
}
struct Link: Codable {
let urls: [URLString]?
let collection: [Collection]?
let about: [About]?
let author: [Author]?
let replies: [Replies]?
let versionHistory: [Version]?
let predecessorVersion: [Predecessor]?
let wpFeaturedmedia: [Featured]?
let wpAttachment: [Attachment]?
let wpTerm: [Term]?
let curies: [Curies]?
enum CodingKeys: String, CodingKey {
case urls = "urls"
case collection = "collection"
case about = "about"
case author = "author"
case replies = "replies"
case versionHistory = "version-history"
case predecessorVersion = "predecessor-version"
case wpFeaturedmedia = "wp:featuredmedia"
case wpAttachment = "wp:attachment"
case wpTerm = "wp:term"
case curies = "curies"
}
}
struct About: Codable{
let href : String?
}
struct Author: Codable {
let embeddable: Bool?
let href : String?
}
struct Replies: Codable {
let embeddable: Bool?
let href : String?
}
struct Version: Codable {
let count: Int?
let href : String?
}
struct Predecessor: Codable {
let id: Int?
let href : String?
}
struct Featured: Codable {
let embeddable: Bool?
let href : String?
}
struct Attachment: Codable{
let href : String?
}
struct Term: Codable {
let taxonomy: String?
let embeddable: Bool?
let href: String?
}
struct Curies: Codable {
let name: String?
let href: String?
let templated: Bool?
}
My decode code:
class func path_getPosts(per_page:Int) -> URL {
let s = APIwp.base + APIwp.posts + APIwp.per_page + "\(per_page)"
print(s)
return URL(string: s)!
}
static func getPosts(for per_page: Int, completion: #escaping ([Wordpress], Error?) -> Void) {
taskGetPosts(url: path_getPosts(per_page: per_page), responseType: [Wordpress].self) { (response, error) in
if let response = response {
completion(response, nil)
} else {
completion([], error)
}
}
}
#discardableResult static func taskGetPosts<ResponseType: Decodable>(url: URL, responseType: ResponseType.Type, completion: #escaping (ResponseType?, Error?) -> Void) -> URLSessionDataTask {
let task = URLSession.shared.dataTask(with: url) { (data, response, error)
in
guard let data = data else {
DispatchQueue.main.async {
completion(nil, error)
}
return
}
let decoder = JSONDecoder()
do {
let responseObject = try decoder.decode(ResponseType.self, from: data)
DispatchQueue.main.async { completion(responseObject, nil) }
} catch let jsonErr {
print("Error:=: \(jsonErr)")
DispatchQueue.main.async { completion(nil, error) }
}
}
task.resume()
return task
}

Please read the error message carefully.
It tells you that the first item (_JSONKey(stringValue: "Index 0", intValue: 0)) in the array for key tags (CodingKeys(stringValue: "tags", intValue: nil) in the first item of the root object (_JSONKey(stringValue: "Index 0", intValue: 0) is not a string, it's a number (Expected to decode String but found a number instead).
So tags is probably [Int]

Related

Swiift - Decoding json data from server

Im working on a project where I have to display data from a network call. The problem is Im having trouble decoding data the data that I received from the network call and storing it into structs variable to use for other calls. The deadline is coming close and Im not sure why my code does not work. This is json that I receive back
{"result":{"login":{"isAuthorized":true,"isEmpty":false,"userName":{"isEmpty":false,"name":{"firstName":"Jason","lastName":"Test","displayName":"Test, Jason","isEmpty":false,"fullName":"Jason Test"},"canDelete":false,"id":5793,"canModify":false},"username":"test#testable.com"},"parameters":{"isEmpty":false,"keep_logged_in_indicator":false,"username":"test#testable.com"}},"isAuthorized":true,"version":{"major":"2021","minor":"004","fix":"04","display":"2021.004.04","isEmpty":false},"isSystemDown":false,"timestamp":"2021-07-26T20:21:43Z","isSuccess":true}
This is the different struct that I made in my project
struct ApiResponse: Decodable {
let results: Results?
let isAuthorized: Bool?
let version: Version?
let isSystemDown: Bool?
let errors: [serverError]?
let timestamp: Date?
let isSuccess: Bool?
}
// MARK: - Result
struct Results: Decodable {
let login: Login
let parameters: Parameters?
}
// MARK: - Login
struct Login: Decodable {
let isAuthorized, isEmpty: Bool?
let userName: UserName
let username: String?
}
// MARK: - UserName
struct UserName: Decodable {
let isEmpty: Bool?
let name: Name
let canDelete: Bool?
let id: Int
let canModify: Bool?
}
// MARK: - Name
struct Name: Decodable {
let firstName, lastName, displayName: String
let isEmpty: Bool?
let fullName: String
}
// MARK: - Parameters
struct Parameters: Decodable {
let isEmpty, keepLoggedInIndicator: Bool?
let username: String?
enum CodingKeys: String, CodingKey {
case isEmpty
case keepLoggedInIndicator
case username
}
}
// MARK: - Version
struct Version: Decodable {
let major, minor, fix, display: String?
let isEmpty: Bool?
}
// Mark: - Error
struct serverError: Decodable {
let password: String?
}
The code that I am using to decode the json data is this
private func handleResponse<T: Decodable>(result: Result<Data, Error>?, completion: (Result<T, Error>) -> Void) {
guard let result = result else {
completion(.failure(AppError.unknownError))
return
}
switch result {
case .success(let data):
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print("Server JsonObject response: \(json)")
} catch {
completion(.failure(error))
}
let decoder = JSONDecoder()
// decodes the Server response
guard let response = try? decoder.decode(ApiResponse.self, from: data) else {
print("Something happen here")
completion(.failure(AppError.errorDecoding))
return
}
// Returns if an error occurs
if let error = response.errors {
completion(.failure(AppError.serverError(error)))
return
}
// Decodes the data received from server
if let decodedData = response.results {
completion(.success(decodedData as! T))
} else {
completion(.failure(AppError.errorDecoding))
}
case .failure(let error):
completion(.failure(error))
}
}
If anyone could help me understand why my code isnt working that would be much appreciated.
Your struct is wrong. Try using this?
struct YourAPIData {
struct Root: Codable {
struct Result: Codable {
struct Login: Codable {
let isAuthorized: Bool
let isEmpty: Bool
struct UserName: Codable {
let isEmpty: Bool
struct Name: Codable {
let firstName: String
let lastName: String
let displayName: String
let isEmpty: Bool
let fullName: String
}
let name: Name
let canDelete: Bool
let id: Int
let canModify: Bool
}
let userName: UserName
let username: String
}
let login: Login
struct Parameters: Codable {
let isEmpty: Bool
let keepLoggedInIndicator: Bool
let username: String
private enum CodingKeys: String, CodingKey {
case isEmpty
case keepLoggedInIndicator = "keep_logged_in_indicator"
case username
}
}
let parameters: Parameters
}
let result: Result
let isAuthorized: Bool
struct Version: Codable {
let major: String
let minor: String
let fix: String
let display: Date
let isEmpty: Bool
}
let version: Version
let isSystemDown: Bool
let timestamp: String
let isSuccess: Bool
}
}
and try using
do {
let APIData = try JSONDecoder().decode(YourAPIData.Root.self, from: jsonData)
} catch let jsonErr { print("Error: ", jsonErr) }
And if you would like to display your json (for testing, i suppose?)
if let data = jsonData, let body = String(data: jsonData, encoding: .utf8) {
print(body)
}
} else {
print(error ?? "Unknown error")
}

Extending a class model for generic type Swift

I am passing API response with Moya and getting this value. I am able to get the object but I extented a base response to handle extra parameters but the extended value does not seem to work. The data expected could be an array of objects and it could just be a regular object. After passing this values, It stopped working and data is not got but every other parameter like status , message are passed except data. Here is my Base response and how I used it
class MaxResponseBase: Codable {
var status: String?
var message: String?
var pagination: Pagination?
var isSucessful: Bool {
return status == "success"
}
struct ErrorMessage {
static let passwordInvalid = " Current password is invalid."
static let loginErrorIncorrectInfo = " Incorrect username/password."
static let loginErrorAccountNotExist = " Invalid request"
}
}
class MaxResponse<T: Codable>: MaxResponseBase {
var data: T?
}
class MaxArrayResponse<T: Codable>: MaxResponseBase {
var data = [T]()
}
Here is my API call for signin for example
func signin(email: String, password: String) -> Observable<MaxResponse<AuthResponse>> {
return provider.rx.request(.signin(username: email, password: password))
.filterSuccess()
.mapObject(MaxResponse<AuthResponse>.self)
.asObservable()
}
how can I tweak this to get data object also
JSON
{
"status" : "success",
"data" : {
"is_locked" : false,
"__v" : 0,
"created_at" : "2019-04-15T11:57:12.551Z"
}
}
It could also be an array of data
(Note: all the code below can be put in a Playground to show that it works.)
In order to solve this, you have to manually write all your initializers. I posted the code that does most of it below but I strongly recommend you use structs instead of classes. It is better in every way if you use structs and containment instead of classes and inheritance.
struct Pagination: Codable { }
struct AuthResponse: Codable {
let isLocked: Bool
let __v: Int
let createdAt: Date
}
class MaxResponseBase: Codable {
let status: String?
let message: String?
let pagination: Pagination?
var isSucessful: Bool {
return status == "success"
}
struct ErrorMessage {
static let passwordInvalid = " Current password is invalid."
static let loginErrorIncorrectInfo = " Incorrect username/password."
static let loginErrorAccountNotExist = " Invalid request"
}
enum CodingKeys: String, CodingKey {
case status, message, pagination
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(String?.self, forKey: .status)
message = try? container.decode(String?.self, forKey: .message) ?? nil
pagination = try? container.decode(Pagination?.self, forKey: .pagination) ?? nil
}
}
class MaxResponse<T: Codable>: MaxResponseBase {
let data: T?
enum DataCodingKeys: String, CodingKey {
case data
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DataCodingKeys.self)
data = try container.decode(T?.self, forKey: .data)
try super.init(from: decoder)
}
}
let json = """
{
"status" : "success",
"data" : {
"is_locked" : false,
"__v" : 0,
"created_at" : "2019-04-15T11:57:12.551Z"
}
}
"""
let data = json.data(using: .utf8)!
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd'T'HH:mm:ss.SSZ"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let response = try decoder.decode(MaxResponse<AuthResponse>.self, from: data)
print(response)
It is far simpler and less code to just use a struct:
struct AuthResponse: Codable {
struct ResponseData: Codable {
let isLocked: Bool
let __v: Int
let createdAt: Date
}
let status: String?
let data: ResponseData
}
let json = """
{
"status" : "success",
"data" : {
"is_locked" : false,
"__v" : 0,
"created_at" : "2019-04-15T11:57:12.551Z"
}
}
"""
let data = json.data(using: .utf8)!
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd'T'HH:mm:ss.SSZ"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let response = try decoder.decode(AuthResponse.self, from: data)
print(response)
And if you really need the MaxResponse type, then make it a protocol and have your other types conform to it. I'm almost willing to bet that you don't need it though.
In response to your comments, here is a generic solution using structs:
struct LoginResponseData: Codable {
let isLocked: Bool
let __v: Int
let createdAt: Date
}
struct BlogResponseData: Codable {
let xxx: Bool
let yyy: Int
let createdAt: Date
}
struct BaseRresponse<ResponseData: Codable>: Codable {
let status: String?
let data: ResponseData
}

keyNotFound(CodingKeys(stringValue: "coord", intValue: nil)

I am building a small swift weather app using the openweatherAPI and I am running into some issues trying to parse the JSON. I have used the following function to parse the get and parse the json.
Below is my weather data struct:
struct WeatherData: Codable {
let coord: Coord
let weather: [Weather]
let base: String
let main: Main
let visibility: Int
let wind: Wind
let clouds: Clouds
let dt: Int
let sys: Sys
let id: Int
let name: String
let cod: Int
}
struct Clouds: Codable {
let all: Int
}
struct Coord: Codable {
let lon, lat: Double
}
struct Main: Codable {
let temp: Double
let pressure, humidity: Int
let tempMin, tempMax: Double
enum CodingKeys: String, CodingKey {
case temp, pressure, humidity
case tempMin = "temp_min"
case tempMax = "temp_max"
}
}
struct Sys: Codable {
let type, id: Int
let message: Double
let country: String
let sunrise, sunset: Int
}
struct Weather: Codable {
let id: Int
let main, description, icon: String
}
struct Wind: Codable {
let speed: Double
let deg: Int
}
private func getWeatherData(url: String, parameters: [String : String]) {
let JsonURLString:[String: Any] = ["url": WEATHER_URL, "parameters": parameters]
print(JsonURLString)
let urlString = JsonURLString["url"] as? String
guard let url = URL(string: urlString!) else { return }
URLSession.shared.dataTask(with: url) { ( data, response, err ) in
DispatchQueue.main.sync {
if let err = err {
print("Failed to get data from url:", err)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let city = try decoder.decode(WeatherData.self, from: data)
self.weatherData.description = city.weather[0].description
self.weatherData.temperature = Int(city.main.temp - 273)
self.weatherData.city = city.name
self.weatherData.condition = city.weather[0].id
self.updateUIWeatherData()
} catch {
print(error)
self.cityLabel.text = "Connection issues"
}
}
}.resume()
}
The exact error I am getting is the following:
longitude = -0.1337, latitude = 51.50998
["parameters": ["lat": "51.50998", "long": "-0.1337", "appid": "xxxxxxxxxxxxxxxxxx"], "url": "https://api.openweathermap.org/data/2.5/weather"]
keyNotFound(CodingKeys(stringValue: "coord", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"coord\", intValue: nil) (\"coord\").", underlyingError: nil))
I have looked at the following example and don't see how this would apply. Any help would be appreciated.
Icon is not appearing. Here is my model:
import UIKit
class WeatherDataModel {
//Declare your model variables here
var temperature: Int = 0
var condition: Int = 0
var city: String = ""
var weatherIconName = ""
var description: String = ""
//This method turns a condition code into the name of the weather condition image
func updateWeatherIcon(condition: Int) -> String {
switch (condition) {
case 0...300 :
return "tstorm1"
case 301...500 :
return "light_rain"
case 501...600 :
return "shower3"
case 601...700 :
return "snow4"
case 701...771 :
return "fog"
case 772...799 :
return "tstorm3"
case 800 :
return "sunny"
case 801...804 :
return "cloudy2"
case 900...903, 905...1000 :
return "tstorm3"
case 903 :
return "snow5"
case 904 :
return "sunny"
default :
return "dunno"
}
}
}
I have added my own icons. I have added this in the do catch block.
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let city = try decoder.decode(WeatherData.self, from: data)
print(city)
self.weatherData.description = city.weather[0].description
self.weatherData.temperature = Int(city.main.temp - 273)
self.weatherData.city = city.name
self.weatherData.condition = city.weather[0].id
self.weatherData.weatherIconName = WeatherDataModel.updateWeatherIcon(self.weatherData.condition)
self.updateUIWeatherData()
} catch {
print(error)
self.cityLabel.text = "Connection issues"
}
The error I am getting this error now:
Instance member 'updateWeatherIcon' cannot be used on type 'WeatherDataModel'; did you mean to use a value of this type instead?
You are creating only the openweathermap URL but you ignore the parameters.
Use something like this for example URLComponents and URLQueryItem to build the URL query properly
private func getWeatherData(parameters: [String : String]) {
guard let lat = parameters["lat"],
let long = parameters["long"],
let appID = parameters["appid"] else { print("Invalid parameters"); return }
var urlComponents = URLComponents(string: "https://api.openweathermap.org/data/2.5/weather")!
let queryItems = [URLQueryItem(name: "lat", value: lat),
URLQueryItem(name: "lon", value: long),
URLQueryItem(name: "appid", value: appID)]
urlComponents.queryItems = queryItems
guard let url = urlComponents.url else { return }
URLSession.shared.dataTask(with: url) { ( data, response, err ) in
DispatchQueue.main.async { // never, never, never sync !!
if let err = err {
print("Failed to get data from url:", err)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let city = try decoder.decode(WeatherData.self, from: data)
print(city)
self.weatherData.description = city.weather[0].description
self.weatherData.temperature = Int(city.main.temp - 273)
self.weatherData.city = city.name
self.weatherData.condition = city.weather[0].id
self.updateUIWeatherData()
} catch {
print(error)
self.cityLabel.text = "Connection issues"
}
}
}.resume()
}
and pass only
["lat": "51.50998", "long": "-0.1337", "appid": "xxxxxxxxxxxxxxxxxx"]
as parameters.

Getting Nil trying to decode json

I'm trying to decode the Json from this URL(:
https://api.letsbuildthatapp.com/appstore/featured
from "Lets build that app tutorials"
This is the code I wrote:
import UIKit
class AppCategory: NSObject{
var name: String?
var apps: [App]?
static func fetchedFeaturedApps(){
let jsonUrlString = "https://api.letsbuildthatapp.com/appstore/featured"
guard let url = URL(string: jsonUrlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else {return}
do{
let featured = try JSONDecoder().decode(Featured.self, from: data)
}catch{
print(err)
}
}.resume()
}
}
struct Featured: Decodable {
var bannerCategory: Banner?
var featuredCategories: [mCategory]?
}
struct Banner: Decodable {
var name: String?
var apps: [String]?
var type: String?
}
struct mCategory: Decodable {
var name: String?
var apps: [App]?
var type: String?
}
struct App: Decodable {
var id: Int?
var name: String?
var category: String?
var price: Float?
var imageName: String?
}
I tried to follow the tutorial but It didn't work for me.
I always get nil while trying to decode the json from the url. I'm really new to this and can't figure out what I'm doing wrong. I know to decode the json properly I need to have Structs as same as the json (like an app array in category) but it still won't work.
EDIT: Should've mentioned, When I run it, the code goes into the catch block and printing "nil".
I tried printing the 'err' but this is all I get in the log:
2019-02-09 19:07:45.241000+0200 AppStore[2344:120273] [AXMediaCommon] Unable to look up screen scale
2019-02-09 19:07:45.241153+0200 AppStore[2344:120273] [AXMediaCommon] Unexpected physical screen orientation
2019-02-09 19:07:45.314112+0200 AppStore[2344:120273] [AXMediaCommon] Unable to look up screen scale
2019-02-09 19:07:45.319977+0200 AppStore[2344:120273] [AXMediaCommon] Unable to look up screen scale
2019-02-09 19:07:45.320189+0200 AppStore[2344:120273] [AXMediaCommon] Unexpected physical screen orientation
nil
You have
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "bannerCategory", intValue: nil)], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))
you need
struct Featured: Codable {
let bannerCategory: BannerCategory
let categories: [Category]
}
struct BannerCategory: Codable {
let name: String
let apps: [BannerCategoryApp]
let type: String
}
struct BannerCategoryApp: Codable {
let imageName: String
enum CodingKeys: String, CodingKey {
case imageName = "ImageName"
}
}
struct Category: Codable {
let name: String
let apps: [CategoryApp]
let type: String
}
struct CategoryApp: Codable {
let id: Int?
let name, category: String?
let price: Double?
let imageName: String
enum CodingKeys: String, CodingKey {
case id = "Id"
case name = "Name"
case category = "Category"
case price = "Price"
case imageName = "ImageName"
}
}
class AppCategory: NSObject{
var name: String?
var apps: [CategoryApp]?
static func fetchedFeaturedApps(){
let jsonUrlString = "https://api.letsbuildthatapp.com/appstore/featured"
guard let url = URL(string: jsonUrlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else {return}
do{
let featured = try JSONDecoder().decode(Featured.self, from: data)
print(featured)
}catch{
print(error)
}
}.resume()
}
}

How to handle dynamic keys from json response using Swift 4 coding keys

In my app i am getting the response like this how i will handle this kind of response which has this which has dynamic keys in every data array
{
"code": 200,
"message": "Top Likers info.",
"error": null,
"data": {
"manishamohapatra11": {
"id": "5591322611",
"username": "manishamohapatra11",
"full_name": ":-)Sunshine :-)",
"profile_pic_url": "https://scontent-atl3-1.cdninstagram.com/vp/d2ba431ac70ec067d5d6def73a721250/5B553C8E/t51.2885-19/s150x150/27877706_168319037141873_8387886458379173888_n.jpg",
"followed_by_viewer": true,
"requested_by_viewer": false,
"likeCount": 7
},
"chrysxnthemxm": {
"id": "5658970660",
"username": "chrysxnthemxm",
"full_name": "Quotes and Sayings",
"profile_pic_url": "https://scontent-atl3-1.cdninstagram.com/vp/f1fb37c94c181d49d9997e24b5d70068/5B40EF01/t51.2885-19/s150x150/20478547_331538517270771_7021810425566068736_a.jpg",
"followed_by_viewer": true,
"requested_by_viewer": false,
"likeCount": 4
}
}
}
i have created structure response
// A struct that conforms to the CodingKey protocol
// It defines no key by itself, hence the name "Generic"
struct GenericCodingKeys: CodingKey {
var stringValue: String
var intValue: Int?
init?(stringValue: String) { self.stringValue = stringValue }
init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
}
struct Response: Decodable {
// Define the inner model as usual
struct User: Decodable {
var id: String
var userName: String
var fullName: String
var profilePicURL: URL
var followedByViewer: Bool
var requestedByViewer: Bool
var likeCount: Int
private enum CodingKeys: String, CodingKey {
case id
case userName = "username"
case fullName = "full_name"
case profilePicURL = "profile_pic_url"
case followedByViewer = "followed_by_viewer"
case requestedByViewer = "requested_by_viewer"
case likeCount
}
}
var code: Int
var message: String
var error: String?
var users: [User]
private enum CodingKeys: String, CodingKey {
case code, message, error, data
}
// You must decode the JSON manually
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.code = try container.decode(Int.self, forKey: .code)
self.message = try container.decode(String.self, forKey: .message)
self.error = try container.decodeIfPresent(String.self, forKey: .error)
self.users = [User]()
let subContainer = try container.nestedContainer(keyedBy: GenericCodingKeys.self, forKey: .data)
for key in subContainer.allKeys {
let user = try subContainer.decode(User.self, forKey: key)
self.users.append(user)
}
}
}
You can try this type...
let arrTemp:NSArray = data.allKeys as NSArray
print(arrTemp)
let strData:NSDictionary = param.value(forKey: arrTemp.object(at: index) as! String) as! NSDictionary
print(strData)