Есть ли способ декодировать ключ JSON в кодируемое свойство с другим именем в структуре в Swift?

У меня есть API, к которому я делаю сетевой запрос, и API возвращает некоторые данные JSON.

Судя по тому, что я видел, наиболее распространенный и общепринятый способ обработки этих данных JSON и работы с ними — это создать структуру Codable, а затем декодировать данные JSON в структуру Как этот пример взлома с помощью Swift.

Однако у меня возникла проблема, и мне нужна помощь. В проект Xcode включен некоторый код персистентности (который Xcode не позволяет мне изменять), который использует структуру с именем «Item». API, который я использую, имеет ключ в JSON, также называемый «Элемент». Когда я создаю свою структуру Codable, я (как и ожидалось) получаю сообщение об ошибке, в котором говорится, что существует «Недопустимое повторное объявление элемента», поскольку оно объявлено в коде персистентности.

Мой вопрос: есть ли способ создать структуру Codable и при этом иметь возможность использовать декодирование JSON для сопоставления поля «Элемент» из данных JSON с полем с другим именем в структуре Codable (т. е. что-то вроде «Товары» или «Продукты») .

Допустим, это данные JSON:

{
    "items": [
                 { "id": 12345 },
                 { "id": 67890 },
                 { "id": 10111 },
                 { "id": 21314 }
    ]
}

И это структура:

struct Order: Codable {
    let items: [Item]
}

struct Item: Codable {
    let id: Int
}

Есть ли способ переименовать элемент (в моей структуре) во что-то другое и при этом декодировать элемент из JSON в структуру?

Что не так с кодом выше? Я почти уверен, что с этим JSON он будет работать.

sonle 25.06.2024 05:04
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
1
94
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

да, вы можете «... сопоставить поле «Элемент» из данных JSON с полем с другим именем в структуре Codable (т. е. что-то вроде «Товары» или «Продукты»)»,

используя enum CodingKeys:..., например:

struct Order: Codable {
    let products: [Product]
    
    enum CodingKeys: String, CodingKey {
        case products = "items"
    }
}

struct Product: Codable {
    let product: Int
    
    enum CodingKeys: String, CodingKey {
        case product = "id"
    }
}

// alternatively keeping the id
struct Product: Codable, Identifiable {
    let id: Int
}

Я просто хочу убедиться, что я правильно понимаю. Перечисление ключей кодирования в структуре заказа говорит о том, что альтернативное имя для продуктов — это элементы (как показано в JSON). В структуре Product альтернативное имя свойства продукта — id?

brandontod97 25.06.2024 17:36

Вы можете дать структуре своих моделей Swift (Заказ, Продукт) любое имя, которое захотите, и, используя enum CodingKeys, вы можете дать любое имя их свойствам (например, пусть продукты) для сопоставления с соответствующими ключами объектов данных JSON (например, элементы). Перечисление CodingKeys в struct Order сообщит JSONDecoder() декодировать объекты JSON с ключом items данных в сохраненное свойство products в struct Order. Дополнительную информацию см. в документации на сайте CodingKeys.

workingdog support Ukraine 26.06.2024 00:43

Обратите внимание: использование enum CodingKeys не изменит данные JSON. Это просто означает сопоставление ключа объекта JSON items данных со свойством структуры Order products. Итак, ключ объекта данных JSON items становится свойством products в файле struct Order. Каждый из них декодируется как тип struct Product, который сопоставляет объект данных JSON с ключом id. И эту клавишу id можно переименовать в product, если вы хотите, чтобы она называлась так в struct Product.

workingdog support Ukraine 26.06.2024 01:02

Итак, если я правильно понял, у вас уже есть структура/класс с именем Item, поэтому вот несколько альтернатив из вашего исходного кода:

struct Order: Codable {
    let items: [Item]
}

struct Item: Codable {
    let id: Int
}

Имя структуры не обязательно должно быть Item, вы можете просто переименовать ее:

struct Order: Codable {
    let items: [Product]
}

struct Product: Codable {
    let id: Int
}

Вы можете вложить Item:

struct Order: Codable {
    let items: [Order.Item] //or [Item]

    struct Item: Codable {
        let id: Int
    }
}

Итак, это все еще «Предмет», но это Order.Item. Внутри Order следует попытаться использовать Order.Item по умолчанию при написании Item. Если вам понадобится различать их позже, это Order.Item и App.Item, где App — ваше имя приложения, или Framework.Item, если Item находится внутри другой структуры.

Не будет ли структура Item, определенная в Order, по-прежнему вызывать ту же ошибку «Недопустимое повторное объявление элемента» (поскольку структура элемента уже объявлена ​​в коде персистентности).

brandontod97 25.06.2024 18:29

Это не должно быть так, потому что Order.Item не является повторным объявлением App.Item.

Larme 25.06.2024 18:38

Другие вопросы по теме