Как я могу обновить метки и заполнитель UIImage из локального JSON? - PullRequest
0 голосов
/ 12 апреля 2019

Итак, у меня есть файл JSON, который мне нужен для анализа и обновления меток и изображений.В моей раскадровке у меня есть 4 ярлыка (изображение животного, регион, его вес и длина) и изображение, где мне нужно поместить его изображение.Мне нужно обновить метки и изображения, анализируя JSON.Вот как далеко я смог добраться до ...

Мой JSON выглядит так:

"data":[
     {
         "name":"Lion",
         "thumbnail":"https://kopelion.org/wp-content/uploads/2016/10/Kimani.jpg",
         "region":"Africa",
         "stats":{
            "max_weight":180,
            "length":250
         }
      }
]

Я пытался проникнуть в это, написав:

override func viewDidLoad() {
        super.viewDidLoad()

        guard let path = Bundle.main.path(forResource: "data", ofType: "json") else { return }
        let url = URL(fileURLWithPath: path)

        do {
            let data = try Data(contentsOf: url)
            let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
            print(json)

            guard let array = json as? [Any] else { return }

            for animal in array {
                guard let animalDict = animal as? [String: Any] else { return }
                guard let animalName = animalDict["name"] as? String else { return }
                guard let animalRegion = animalDict["region"] as? String else { return }
                guard let animalStats = animalDict["stats"] as? String else { return }

                print(animalName)
                print(animalRegion)
                print(animalStats)
            }
        } catch {
            print(error)
        }


    }

Ответы [ 3 ]

0 голосов
/ 13 апреля 2019

Во-первых, во-первых, в большинстве случаев основным виновником является json сам файл, как в вашем случае.

Вам нужно fix код json, сначала adding "{" at the top и"}" at the bottom вашего json кода файла.

Это сделает его valid json

А затем do the following

Замените строки кода:

// 1
guard let array = json as? [Any] else { return }

// 2
guard let animalStats = animalDict["stats"] as? String else { return }

следующим:

// 1
guard let dictionary = json as? [String:[Any]] else { return }
guard let array = dictionary["data"]  else { return }

//2
guard let animalRegion = animalDict["region"] as? String else { return }

Совет: 1. Проверьте свой JSON с помощью онлайн-инструментов, таких как https://codebeautify.org/jsonviewer

Попробуйте использовать JSONDecoder и JSONEncoder вместо JSONSerialization
0 голосов
/ 13 апреля 2019

Поскольку вы несете ответственность за JSON, удалите вмещающий словарь data, он не нужен.

[{
   "name":"Lion",
   "thumbnail":"https://kopelion.org/wp-content/uploads/2016/10/Kimani.jpg",
   "region":"Africa",
   "stats":{
      "max_weight":180,
      "length":250
   }
}]

Создайте две структуры

struct Animal: Decodable {
    let name: String
    let thumbnail: URL
    let region: String
    let stats: Stats
}

struct Stats: Decodable {
    let maxWeight, length: Int
}

В контроллере представления объявите данныеисходный массив

var animals = [Animal]()

В viewDidLoad анализирует данные с помощью JSONDecoder и присваивает результат массиву источника данных

override func viewDidLoad() {
    super.viewDidLoad()

    let url = Bundle.main.url(forResource: "data", withExtension: "json")!
    let data = try! Data(contentsOf: url)
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    self.animals = try! decoder.decode([Animal].self, from: data)
}

Все guard с и try сна самом деле не нужны.Файл должен существовать во время компиляции и не может быть изменен во время выполнения, поэтому код не должен давать сбой.

Вы можете получить свойства животного с помощью

let animal = animals[0]
let name = animal.name
let weight = animal.stats.weight
print(name, weight)

Предполагая, что естьбольше животных в JSON используют цикл

for animal in animals {
    let name = animal.name
    let weight = animal.stats.weight
    print(name, weight)
}

Как обновить метки неясно, потому что в вашем вопросе нет существенной информации о дизайне.

Чтобы получить изображение, загрузите егоасинхронно с URLSession

0 голосов
/ 12 апреля 2019

В вашем классе должны быть свойства для элементов раскадровки, которые вы хотите установить. например,:.

@IBOutlet weak var name: UILabel! // outside functions but inside class, and hooked up in Storyboard

// inside viewDidLoad

name.text = animalDict["name"] as? String

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...