Используйте ключи из объекта JSON для анализа данных и отображения в виде списка - PullRequest
0 голосов
/ 21 июня 2020

У меня есть API, который возвращает объект JSON с ключами: http://acnhapi.com/v1/bugs

Поскольку это не массив, я хотел бы понять, как его перемещать. Я пытаюсь получить список ошибок с именами «обычная бабочка» и «желтая бабочка» и т. Д. c. используя их ключи common_butterfly и yellow_butterfly et c.

Я хочу вывести значение common_butterfly.name.name-USen, но для каждой ошибки. Итак, мой список должен в конечном итоге отображаться как:

  • обычная бабочка
  • желтая бабочка
  • тигровая бабочка
  • et c.

(в алфавитном порядке будет бонусом)

данные

import SwiftUI

struct Bugs: Codable, Identifiable {
    let id = UUID()
    var name: String
}

class FetchBugs: ObservableObject {
  @Published var bugs = [Bugs]()
     
    init() {
        let url = URL(string: "http://acnhapi.com/v1/bugs")!
        URLSession.shared.dataTask(with: url) {(data, response, error) in
            do {
                if let bugsData = data {
                    let decodedData = try JSONDecoder().decode([Bugs].self, from: bugsData)
                    DispatchQueue.main.async {
                        self.bugs = decodedData
                    }
                } else {
                    print("No data")
                }
            } catch {
                print("Error")
            }
        }.resume()
    }
}

список

import SwiftUI

struct BugList: View {
    @ObservedObject var fetch = FetchBugs()
    var body: some View {
        VStack {
            List(fetch.bugs) { bug in
                VStack(alignment: .leading) {
                    Text(bug.name)
                }
            }
        }
    }
}

struct BugList_Previews: PreviewProvider {
    static var previews: some View {
        BugList()
    }
}

Ответы [ 2 ]

1 голос
/ 21 июня 2020

С помощью этого решения вы можете декодировать все ваши локализованные имена:

struct Bug: Decodable, Identifiable {
    enum CodingKeys: String, CodingKey { case name }
    
    let id = UUID()
    var localizedNames: [String: String] = [:]
    
    var nameUSen: String {
        localizedNames["name-USen"] ?? "error"
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let names = try container.decode([String: String].self, forKey: .name)
        for (key, value) in names {
            localizedNames[key] = value
        }
    }
}

Используйте .sorted { $0.nameUSen < $1.nameUSen } для сортировки ваших данных:

class FetchBugs: ObservableObject {
    @Published var bugs = [Bug]()

    init() {
        let url = URL(string: "http://acnhapi.com/v1/bugs")!
        URLSession.shared.dataTask(with: url) { data, response, error in
            do {
                if let bugsData = data {
                    let decodedData = try JSONDecoder().decode([String: Bug].self, from: bugsData)
                    DispatchQueue.main.async {
                        self.bugs = Array(decodedData.values).sorted { $0.nameUSen < $1.nameUSen }
                    }
                } else {
                    print("No data")
                }
            } catch {
                print(error)
            }
        }.resume()
    }
}

И отобразите USen имя:

struct BugList: View {
    @ObservedObject var fetch = FetchBugs()
    var body: some View {
        VStack {
            List(fetch.bugs) { bug in
                VStack(alignment: .leading) {
                    Text(bug.nameUSen)
                }
            }
        }
    }
}

Если вы когда-нибудь захотите получить доступ к любому другому имени, вы можете использовать:

bug.localizedNames["name-EUde"]!
0 голосов
/ 21 июня 2020

Вот игровая площадка, демонстрирующая получение всех имен ошибок в алфавитном порядке:

struct Bug: Decodable, Identifiable {
    let id: Int
    let name: Name

    struct Name: Decodable {
        let nameUSen: String

        enum CodingKeys: String, CodingKey {
            case nameUSen = "name-USen"
        }
    }
}

do {
    let butterflies = try Data(contentsOf: URL(string: "http://acnhapi.com/v1/bugs")!)
    let allBugs = try JSONDecoder().decode([String: Bug].self, from: butterflies)

    let bugs = Array(allBugs.values.sorted { $0.name.nameUSen < $1.name.nameUSen })
    bugs.forEach { print($0.name.nameUSen) }
} catch {
    print(error)
}
...