Декодирование файла JSON в разные целевые массивы - PullRequest
0 голосов
/ 29 января 2020

У меня есть код для декодирования файла JSON, который выглядит следующим образом:

[
  {
    "id" : "WIW-919",
    "factionGroupName" : "CommonWealth",
    "characters" : [
      {
        "id" : "NPJ-160",
        "name" : "Agatha Tavernfrau",
        "faction" : "CommonWealth",
        "mugShot" : "AgathaMugShot",
        "standeeImage" : "AgathaStandee",
        "cardBackImage" : "AgathaSignaturev1",
        "cardFrontImage" : "AgathaFrontv1",
        "keywords" : [
          "Human"
        ]
      },  
  {
    "id" : "PAQ-610",
    "factionGroupName" : "Dominion",
    "characters" : [
      {
        "id" : "JKA-020",
        "name" : "Doug the flatulent",
        "faction" : "Dominion",
        "mugShot" : "DougMugShot",
        "standeeImage" : "DougStandee",
        "cardBackImage" : "DougSignaturev2",
        "cardFrontImage" : "DougFrontv2",
        "keywords" : [
          "Animal",
          "Goblin"
        ]
      }
    ]
  }
]

По сути, у меня есть две структуры верхнего уровня, использующие factionGroupName, которые затем, в свою очередь, используют другую структуру для декодирования символы объектов.

Я могу прочитать в полном файле JSON и в каждом l oop округлить содержимое и вывести его в виде списка. * c.

Однако - что Я действительно хочу сделать, это декодировать файл JSON и поместить массив верхнего уровня в две разные структуры - так что если IF factionGroupName равно CommonWealth, то использовать структуру с именем Commonwealth, но если factionGroupName равно Dominion, использовать другую структуру.

Могу ли я сделать это? Или мне нужно использовать разные JSON файлы?

Я пытаюсь прочитать о том, как я могу использовать пользовательские правила декодера, но я думаю, что я просто хочу провести тест значения для переменной factionGroupName и изменить структура, которую он тогда вызывает?


Это текущий код для чтения в Json:

import SwiftUI
struct markTestName: Codable, Identifiable {
    var id: String
    var factionGroupName: String
    var characters: [charDetail]
}
struct charDetail: Codable, Equatable, Identifiable{
    var id: String
    var name: String
    var faction: String
    var mugShot : String
    var standeeImage : String
    var cardBackImage : String
    var cardFrontImage : String
    var keywords: [String]
}

1 Ответ

1 голос
/ 29 января 2020

Я бы начал с создания пары Codable структур для хранения ваших JSON данных:

struct Faction: Codable {
    let id: String
    let name: String
    let characters: [Character]
}

struct Character: Codable {
    let id: String
    let name: String
    let faction: String
    let mugShot: String
    let standeeImage: String
    let cardBackImage: String
    let cardFrontImage: String
    let keywords: [String]
}

Затем создайте структуру для хранения ваших фракций (и любых других данных, которые вам могут понадобиться)

struct GameData {
    let factions:[Faction]

    var factionNames:[String] {
        get {
            return Array(Set(factions.compactMap({ $0.name })))
        }
    }

    func faction(named: String) -> Faction? {
        return factions.first { (faction) -> Bool in
            faction.name == named
        }
    }     
}

Если factions - это массив [Faction], который вы получаете из JSON, вы должны создать экземпляр GameData, используя

let gameData = GameData(factions: factions)

Теперь вы можете получить определенная фракция, использующая:

if let commonwealth = gameData.faction(named:"Commonwealth") {
   // Do something
} else {
   // Faction not found
}

Поскольку у вас относительно небольшое количество фракций, простое использование first(where:) для поиска в массиве не является большой проблемой производительности, особенно потому, что вы, вероятно, делаете это только один раз и сохранить фракцию в другой переменной.

Вы также можете получить список всех фракций (для динамического создания элементов, таких как кнопки фильтрации фракций), используя gameData.factionNames

...