Создать объект из объекта JSON в Swift 5 - PullRequest
1 голос
/ 14 июня 2019

Необходимо создать объект из объекта JSON

Ответ JSON от API

{
    "id": 1,
    "name": "Cricket",
    "slug": "cricket",
    "banner_image": "https://cricket.jpg",
    "icons": {
        "green": "http://localhost:8000/sport_icon_cricket_green.png",
        "grey": "http://localhost:8000/sport_icon_cricket_gray.png",
        "white": "http://localhost:8000/sport_icon_cricket_white.png",
        "black": "http://localhost:8000/sport_icon_cricket_black.png"
    }
},
{
    "id": 2,
    "name": "Baseball",
    "slug": "baseball",
    "banner_image": "https://baseball.jpg",
    "icons": {
        "green": "http://localhost:8000/sport_icon_baseball_green.png",
        "grey": "http://localhost:8000/sport_icon_baseball_gray.png",
        "white": "http://localhost:8000/sport_icon_baseball_white.png",
        "black": "http://localhost:8000/sport_icon_baseball_black.png"
    }
},

Я создал struct, как показано ниже

Ошибка в нижней строке struct ObjSportsList:Codable

struct ObjSportsList:Codable { // Error on this line -> Error : Type 'ObjSportsList' does not conform to protocol 'Decodable'

    var id:Int
    var name:String
    var slug:String
    var icons:ObjSportsIcon
}

struct ObjSportsIcon {
    var green:String
    var grey:String
    var white:String
    var black:String
}

Декодировать Вот так

let decoderdec = JSONDecoder()
                        decoderdec.keyDecodingStrategy = .convertFromSnakeCase
                        // 2. Create Data from Response
                        let jsonData = try JSONSerialization.data(withJSONObject: jsonResponse["data"] as! [[String:Any]])

                        // 3 Convert Data to Object (Array) if don't user array then only pass ObjCountry.self
                        self.arrSports.removeAll()
                        self.arrSports = try decoderdec.decode([ObjSportsList].self, from: jsonData)

ОШИБКА при декодированиистрока: Невозможно присвоить значение типа '[ObjSportsList]' для типа '[[String: Any]]'

Обновить

// Ошибка 2. Создание данных из ответа // Это массив [[String: Any]] let jsonData = try JSONSerialization.data (withJSONObject: jsonResponse ["data"] как! [[String: Any]])

Ответы [ 2 ]

2 голосов
/ 14 июня 2019

Вам просто не хватало реализации Codable с классом ObjSportsIcon.

struct ObjSportsList : Codable {

    var id:Int
    var name:String
    var slug:String
    var icons:ObjSportsIcon
}

struct ObjSportsIcon : Codable {
    var green:String
    var grey:String
    var white:String
    var black:String
}

ИЛИ Вы можете использовать следующий код, чтобы сделать его правильным:

public struct ObjSportsList : Codable {

    var id:Int
    var name:String
    var slug:String
    var icons:ObjSportsIcon

    public init(id: Int, name: String, slug: String, icons: ObjSportsIcon) {
        self.id = id
        self.name = name
        self.slug = slug
        self.icons = icons
    }

    public enum CodingKeys: String, CodingKey {
        case id
        case name
        case slug
        case icons
    }
}

public struct ObjSportsIcon : Codable {
    var green:String
    var grey:String
    var white:String
    var black:String

    public init(green: String, grey: String, white: String, black: String) {
        self.green = green
        self.grey = grey
        self.white = white
        self.black = black
    }

    public enum CodingKeys: String, CodingKey {
        case green
        case grey
        case white
        case black
    }
}

Изменить следующую строкукод для решения вашей второй ошибки:

self.arrSports = try decoderdec.decode(Array<ObjSportsList>.self, from: jsonData)

Обновление от Vivek:

Я нашел свою ошибку и решение для второй ошибки

Старый код var arrSports:[[String:Any]] = []

Новый код var arrSports:[ObjSportsList] = []


Вы должны реализовать метод init (from decoder: Decoder) для достижения того же самого.Примечание. Необходимо установить значения по умолчанию для каждого свойства

struct ObjSportsIcon : Codable {
    var green:String
    var grey:String
    var white:String
    var black:String
    var pink:String

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.green = try container.decodeIfPresent(String.self, forKey: .green) ?? "green"
        self.grey = try container.decodeIfPresent(String.self, forKey: .grey) ?? "grey"
        self.white = try container.decodeIfPresent(String.self, forKey: .white) ?? "white"
        self.black = try container.decodeIfPresent(String.self, forKey: .black) ?? "black"
        self.pink = try container.decodeIfPresent(String.self, forKey: .pink) ?? "pink"
    }
}
0 голосов
/ 14 июня 2019

Я не знаю, почему возникла проблема, потому что я попытался просто скопировать и вставить ваш код.Все работает нормально.Пожалуйста, обратитесь ниже код.

Класс модели:

struct ObjSportsList : Decodable {
    var id:String
    var name:String
    var slug:String
    var icons:ObjSportsIcon
}

struct ObjSportsIcon : Decodable {
    var green:String
    var grey:String
    var white:String
    var black:String
}

Код разбора:

let decoderdec = JSONDecoder()
decoderdec.keyDecodingStrategy = .convertFromSnakeCase

let aryTemp = [[
        "id": "1",
        "name": "Cricket",
        "slug": "cricket",
        "banner_image": "https://cricket.jpg",
        "icons": [
            "green": "http://localhost:8000/sport_icon_cricket_green.png",
            "grey": "http://localhost:8000/sport_icon_cricket_gray.png",
            "white": "http://localhost:8000/sport_icon_cricket_white.png",
            "black": "http://localhost:8000/sport_icon_cricket_black.png"
    ]],[
        "id": "2",
        "name": "Baseball",
        "slug": "baseball",
        "banner_image": "https://baseball.jpg",
        "icons": [
            "green": "http://localhost:8000/sport_icon_baseball_green.png",
            "grey": "http://localhost:8000/sport_icon_baseball_gray.png",
            "white": "http://localhost:8000/sport_icon_baseball_white.png",
            "black": "http://localhost:8000/sport_icon_baseball_black.png"
        ]
    ]]

do {
    let jsonData = try JSONSerialization.data(withJSONObject: aryTemp)
    let arrSports = try decoderdec.decode([ObjSportsList].self, from: jsonData)        
    print(arrSports)
} catch let error {
    print(error)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...