Как разобрать массив JSON массива в Swift - PullRequest
0 голосов
/ 30 сентября 2019

Я новичок в разборе json, я не могу расшифровать и разобрать, пожалуйста, помогите мне, если кто-нибудь может сделать.

здесь моя модель

struct Welcome: Codable {
let genreID, name, welcomeDescription, slug: String
let url: String
let videos: [Video]
}

struct Video: Codable {
    let videosID, title, videoDescription, slug: String
    let release, isTvseries, runtime: String
    let videoQuality: VideoQuality
    let thumbnailURL, posterURL: String
}

и Пример

[{
"genre_id": "",
"name": "",
"description": "",
"slug": "",
"url": "",
"videos": [
  {
    "videos_id": "",
    "title": "",
    "description": "",
    "slug": "",
    "release": "",
    "is_tvseries": "",
    "runtime": "",
    "video_quality": "",
    "thumbnail_url": "",
    "poster_url": ""
  },
  {
    "videos_id": "",
    "title": "",
    "description": "",
    "slug": "",
    "release": "",
    "is_tvseries": "",
    "runtime": " ",
    "video_quality": "",
    "thumbnail_url": "",
    "poster_url": ""
  }
]}, {
"genre_id": "",
"name": "",
"description": " ",
"slug": "",
"url": "",
"videos": [
  {
    "videos_id": "",
    "title": " ",
    "description": "",
    "slug": "",
    "release": "",
    "is_tvseries": "",
    "runtime": "",
    "video_quality": "",
    "thumbnail_url": "",
    "poster_url": ""
  },
  {
    "videos_id": "",
    "title": "",
    "description": "",
    "slug": "",
    "release": "",
    "is_tvseries": "",
    "runtime": "",
    "video_quality": "",
    "thumbnail_url": "",
    "poster_url": ""
  }
] } ]

Я хочу использовать JSONDecoder() в блоке ответа. Я хочу проанализировать данные JSON от ответа на VC через завершение Хандлер. И кто-то, кто эксперт в завершении, пожалуйста, объясните об этом, чтобы я мог решить мою проблему.

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

Вы должны определить CodingKeys для каждого поля

enum CodingKeys: String {
        case genreId = "genre_id"
        case name = "name"
        case welcomeDescription = "description"
        case slug = "slug"
        case url = "url"
        case videos = "videos"
}

Если вы хотите установить nil для поля пропуска, если не настроено, это приведет к сбою

init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeIfPresent(String.self, forKey: .id).unwrapped(or: "")
        type = try container.decodeIfPresent(String.self, forKey: .type).unwrapped(or: "")
        code = try container.decodeIfPresent(Code.self, forKey: .code).unwrapped(or: .home)
        name = try container.decodeIfPresent(String.self, forKey: .name).unwrapped(or: "")
        value = try container.decodeIfPresent(String.self, forKey: .value).unwrapped(or: "")
    }

И реализовать протокол так же:

typealias JSObject = [String: Any]
typealias JSArray = [JSObject]

protocol Model: Codable {
    func data(encodingKey: JSONEncoder.KeyEncodingStrategy) -> Data?
    func json(encodingKey: JSONEncoder.KeyEncodingStrategy) -> JSObject?
    init?(result: Result<JSObject>?)
    init?(data: Data?)
    init?(json: JSObject?)

    static func mapToArray(result: Result<JSObject>?) -> [Self]?
}

extension Model where Self: Codable {
    static var encoderCamelKey: JSONEncoder {
        let encoder = JSONEncoder()
        encoder.keyEncodingStrategy = .useDefaultKeys
        return encoder
    }

    static var encoderSnakeKey: JSONEncoder {
        let encoder = JSONEncoder()
        encoder.keyEncodingStrategy = .convertToSnakeCase
        return encoder
    }

    static var decoder: JSONDecoder {
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return decoder
    }

    func data(encodingKey: JSONEncoder.KeyEncodingStrategy) -> Data? {
        switch encodingKey {
        case .useDefaultKeys:
            return try? Self.encoderCamelKey.encode(self)
        case .convertToSnakeCase:
            return try? Self.encoderSnakeKey.encode(self)
        default:
            return nil
        }
    }

    func json(encodingKey: JSONEncoder.KeyEncodingStrategy) -> JSObject? {
        guard let data = self.data(encodingKey: encodingKey),
            let jsonObject = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? JSObject
            else { return nil }
        return jsonObject
    }

    init?(data: Data?) {
        guard let data = data else { return nil }
        do {
            let anInstance = try Self.decoder.decode(Self.self, from: data)
            self = anInstance
        } catch {
            dump(error, name: "Model decode failure")
            return nil
        }
    }

    init?(result: Result<JSObject>?) {
        let json = result?.dataJson(type: JSObject.self)
        self.init(data: json?.jsonData())
    }

    init?(json: JSObject?) {
        self.init(data: json?.jsonData())
    }

    static func mapToArray(result: Result<JSObject>?) -> [Self]? {
        let dataJson = result?.dataJson(type: JSArray.self)
        return Self.mapToArray(jsArray: dataJson)
    }

    static func mapToArray(jsArray: JSArray?) -> [Self]? {
        guard let data = jsArray?.data() else { return nil }
        do {
            let anInstance = try Self.decoder.decode([Self].self, from: data)
            return anInstance
        } catch {
            dump(error, name: "Model decode failure")
            return nil
        }
    }

    static func mapArray(jsArray: JSArray?) -> [Self]? {
        guard let data = jsArray?.data() else { return nil }
        do {
            let anInstance = try JSONDecoder().decode([Self].self, from: data)
            return anInstance
        } catch {
            dump(error, name: "Model decode failure")
            return nil
        }
    }
}
0 голосов
/ 30 сентября 2019

После получения Data от API / local вам необходимо decode ответ, как показано ниже,

do {
   let data = //Data from the API
   let welcomeList = try JSONDecoder().decode([Welcome].self, from: data)
   welcomeList.forEach { welcome in 
       welcome.videos.forEach {video in 
          print(video.videosID)
       }
   }
} catch {
   print(error)
}

Чтобы получить бесплатный код для анализа и моделей, вы всегда можете поставить свой JSONв этом веб-приложении . Но вы должны позаботиться о дополнительных свойствах, по умолчанию свойства модели остаются необязательными, поэтому, если вам известно какое-либо свойство, которое может быть возвращено nil в ответ, сделайте его необязательным (? ).

...