У меня есть 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 с полем с другим именем в структуре 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?
Вы можете дать структуре своих моделей Swift (Заказ, Продукт) любое имя, которое захотите, и, используя enum CodingKeys
, вы можете дать любое имя их свойствам (например, пусть продукты) для сопоставления с соответствующими ключами объектов данных JSON (например, элементы). Перечисление CodingKeys в struct Order
сообщит JSONDecoder() декодировать объекты JSON с ключом items
данных в сохраненное свойство products
в struct Order
. Дополнительную информацию см. в документации на сайте CodingKeys.
Обратите внимание: использование enum CodingKeys
не изменит данные JSON. Это просто означает сопоставление ключа объекта JSON items
данных со свойством структуры Order products
. Итак, ключ объекта данных JSON items
становится свойством products
в файле struct Order
. Каждый из них декодируется как тип struct Product
, который сопоставляет объект данных JSON с ключом id
. И эту клавишу id
можно переименовать в product
, если вы хотите, чтобы она называлась так в struct Product
.
Итак, если я правильно понял, у вас уже есть структура/класс с именем 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, по-прежнему вызывать ту же ошибку «Недопустимое повторное объявление элемента» (поскольку структура элемента уже объявлена в коде персистентности).
Это не должно быть так, потому что Order.Item
не является повторным объявлением App.Item
.
Что не так с кодом выше? Я почти уверен, что с этим JSON он будет работать.