Вы можете обрабатывать его методами init (from decoder: Decoder)
if let objHits = try values.decodeIfPresent(Hits.self, forKey: .hits) {
hits = [objHits]
} else {
hits = try values.decodeIfPresent([Hits].self, forKey: .hits)
}
Я буду следовать приведенному ниже фрагменту кода, чтобы правильно его проанализировать.
import Foundation
struct algolia : Codable {
let hits : [Hits]?
let page : Int?
let nbHits : Int?
let nbPages : Int?
let hitsPerPage : Int?
let processingTimeMS : Int?
let query : String?
let params : String?
enum CodingKeys: String, CodingKey {
case hits = "hits"
case page = "page"
case nbHits = "nbHits"
case nbPages = "nbPages"
case hitsPerPage = "hitsPerPage"
case processingTimeMS = "processingTimeMS"
case query = "query"
case params = "params"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let objHits = try values.decodeIfPresent(Hits.self, forKey: .hits) {
hits = [objHits]
} else {
hits = try values.decodeIfPresent([Hits].self, forKey: .hits)
}
page = try values.decodeIfPresent(Int.self, forKey: .page)
nbHits = try values.decodeIfPresent(Int.self, forKey: .nbHits)
nbPages = try values.decodeIfPresent(Int.self, forKey: .nbPages)
hitsPerPage = try values.decodeIfPresent(Int.self, forKey: .hitsPerPage)
processingTimeMS = try values.decodeIfPresent(Int.self, forKey: .processingTimeMS)
query = try values.decodeIfPresent(String.self, forKey: .query)
params = try values.decodeIfPresent(String.self, forKey: .params)
}}
struct Hits : Codable {
let firstname : String?
let lastname : String?
let objectID : String?
let _highlightResult : _highlightResult?
enum CodingKeys: String, CodingKey {
case firstname = "firstname"
case lastname = "lastname"
case objectID = "objectID"
case _highlightResult = "_highlightResult"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
firstname = try values.decodeIfPresent(String.self, forKey: .firstname)
lastname = try values.decodeIfPresent(String.self, forKey: .lastname)
objectID = try values.decodeIfPresent(String.self, forKey: .objectID)
_highlightResult = try values.decodeIfPresent(_highlightResult.self, forKey: ._highlightResult)
}}
struct Firstname : Codable {
let value : String?
let matchLevel : String?
enum CodingKeys: String, CodingKey {
case value = "value"
case matchLevel = "matchLevel"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
value = try values.decodeIfPresent(String.self, forKey: .value)
matchLevel = try values.decodeIfPresent(String.self, forKey: .matchLevel)
}}
struct _highlightResult : Codable {
let firstname : Firstname?
let lastname : Lastname?
let company : Company?
enum CodingKeys: String, CodingKey {
case firstname = "firstname"
case lastname = "lastname"
case company = "company"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
firstname = try values.decodeIfPresent(Firstname.self, forKey: .firstname)
lastname = try values.decodeIfPresent(Lastname.self, forKey: .lastname)
company = try values.decodeIfPresent(Company.self, forKey: .company)
}}
По вашему мнению, контроллером используйте следующий код
func jsonToCodable<T: Codable>(json: [String: Any], codable: T.Type) -> T? {
let decoder = JSONDecoder()
do {
let data = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
let codable = try decoder.decode(codable, from: data)
return codable
} catch {
print("*/ json failed */")
print(error)
//print(error.localizedDescription)
print(json)
}
return nil
}
if let algoliaObject = jsonToCodable(json: jsonictionary, codable: algolia.self) {// using optional chaining access _highlightResult }