Ответ
[
{
"result": "success",
"category": [
{
"categoryID": "1",
"category_name": "Health",
"category_image": "1573456796.jpg",
"about": "Start your health journey with scientifically developed, guided meditations across below listed verticals",
"color": "",
"special": "N",
"tags": "fitness|energy|strength",
"is_active": "Y",
"description": "Explore guided health meditations to build stronger emotional, mental & physical health",
"added_on": "2019-11-22 03:21:36",
"no_items": "7"
},
{
"categoryID": "2",
"category_name": "Work",
"category_image": "1556794807.jpg",
"about": "Accelerate your work life with scientifically developed, guided meditations across below listed verticals ",
"color": "",
"special": "N",
"tags": null,
"is_active": "Y",
"description": "Explore guided work meditations to release stress, foster progressive mindset & excel at work.",
"added_on": "2019-05-02 04:30:07",
"no_items": "2"
},
{
"categoryID": "3",
"category_name": "Relationships",
"category_image": "1556794814.jpg",
"about": "Illuminate your relations with scientifically developed, guided meditations across below listed verticals",
"color": "",
"special": "N",
"tags": null,
"is_active": "Y",
"description": "Explore guided relationship meditations to create a deep & loving bond with the self and others",
"added_on": "2019-05-02 04:30:14",
"no_items": "0"
},
{
"categoryID": "4",
"category_name": "Mindfulness",
"category_image": "1556794819.jpg",
"about": "Rewire your brain & turn your NOW into WOW™ with scientifically developed, guided mindfulness meditations",
"color": "",
"special": "N",
"tags": null,
"is_active": "Y",
"description": "Explore guided mindfulness meditations to develop focus & awareness in order to turn your NOW into WOW™",
"added_on": "2019-05-02 04:30:19",
"no_items": "0"
},
{
"categoryID": "5",
"category_name": "Students",
"category_image": "1556794824.jpg",
"about": "Spark up your student life with scientifically developed, guided meditations across below listed verticals ",
"color": "",
"special": "N",
"tags": null,
"is_active": "Y",
"description": "Explore guided student meditations to strengthen mind power in order to emerge as a super student",
"added_on": "2019-05-02 04:30:24",
"no_items": "0"
},
{
"categoryID": "6",
"category_name": "Affirmations",
"category_image": "1556794832.jpg",
"about": "Prime your mind, body & emotions with scientifically developed, affirmations across below listed verticals.",
"color": "",
"special": "N",
"tags": "tags|testing|search",
"is_active": "Y",
"description": "Explore guided affirmations to train your mind & body to unleash the infinite potential within",
"added_on": "2019-05-02 04:30:32",
"no_items": "0"
}
]
}
]
Ошибка
typeMismatch (Swift.Dictionary, Swift.DecodingError.Context (codingPath: [ ], debugDescription: «Ожидается декодирование словаря, но вместо него найден массив.», underError: nil))
Реализация
import Foundation
import Alamofire
struct Library : Codable {
let result : String?
let category : [Category]?
enum CodingKeys: String, CodingKey {
case result = "result"
case category = "category"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
result = try values.decodeIfPresent(String.self, forKey: .result)
category = try values.decodeIfPresent([Category].self, forKey: .category)
}
}
struct Category : Codable {
let categoryID : String?
let category_name : String?
let category_image : String?
let about : String?
let color : String?
let special : String?
let tags : String?
let is_active : String?
let description : String?
let added_on : String?
let no_items : String?
enum CodingKeys: String, CodingKey {
case categoryID = "categoryID"
case category_name = "category_name"
case category_image = "category_image"
case about = "about"
case color = "color"
case special = "special"
case tags = "tags"
case is_active = "is_active"
case description = "description"
case added_on = "added_on"
case no_items = "no_items"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
categoryID = try values.decodeIfPresent(String.self, forKey: .categoryID)
category_name = try values.decodeIfPresent(String.self, forKey: .category_name)
category_image = try values.decodeIfPresent(String.self, forKey: .category_image)
about = try values.decodeIfPresent(String.self, forKey: .about)
color = try values.decodeIfPresent(String.self, forKey: .color)
special = try values.decodeIfPresent(String.self, forKey: .special)
tags = try values.decodeIfPresent(String.self, forKey: .tags)
is_active = try values.decodeIfPresent(String.self, forKey: .is_active)
description = try values.decodeIfPresent(String.self, forKey: .description)
added_on = try values.decodeIfPresent(String.self, forKey: .added_on)
no_items = try values.decodeIfPresent(String.self, forKey: .no_items)
}
}
extension Library {
init(data: Data) throws {
let decoder = JSONDecoder()
self = try decoder.decode(Library.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
init(fromURL url: URL) throws {
try self.init(data: try Data(contentsOf: url))
}
func jsonData() throws -> Data {
return try JSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
// MARK: - Alamofire response handlers
extension DataRequest {
fileprivate func decodableResponseSerializer<T: Decodable>() -> DataResponseSerializer<T> {
return DataResponseSerializer { _, response, data, error in
print(response)
guard error == nil else { return .failure(error!) }
guard let data = data else {
return .failure(AFError.responseSerializationFailed(reason: .inputDataNil))
}
return Result { try JSONDecoder().decode(T.self, from: data) }
}
}
@discardableResult
fileprivate func responseDecodable<T: Decodable>(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<T>) -> Void) -> Self {
return response(queue: queue, responseSerializer: decodableResponseSerializer(), completionHandler: completionHandler)
}
@discardableResult
func responsePhoto(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<Library>) -> Void) -> Self {
return responseDecodable(queue: queue, completionHandler: completionHandler)
}
}