О нет! Это json разбор пирамиды смерти!
Небольшая альтернатива
Если вы знаете структуру json, которую вы будете получать, вы можете создать некоторые структуры для моделирования ваших данных. Также у Swift есть классный протокол, называемый «Codable», который делает много усилий при разборе json и преобразовании его в объект, который вы создаете в коде.
Давайте смоделируем данные!
Мы создадим 2 структуры, которые соответствуют Codable Protocol. Первая будет содержать все данные ответа
struct ApiGameReponse:Codable {
var error:String
var limit:Int
var offset:Int
var pages:Int
var totalResults:Int
var status:Int
var version:String
var games:[Game]
private enum CodingKeys:String, CodingKey {
//The enum's rawValue needs to match the json's fieldName exactly.
//That's why some of these have a different string assigned to them.
case error
case limit
case offset
case pages = "number_of_page_results"
case totalResults = "number_of_total_results"
case status = "status_code"
case version
case games = "results"
}
}
, а вторая структура будет моделировать наш игровой объект. (Это единственная строка, да, я знаю, что это очень увлекательно ...) Поскольку эти конкретные данные json представляют игру только с одним свойством name, нам не нужна целая структура, но если json был другим и скажем, имеет свойства "gamePrice" и "жанр", структура будет лучше смотреть.
struct Game:Codable {
var name:String
}
Сохраняйте это красиво
Спасибо вам, но я не люблю смотреть на уродливый код. Чтобы сохранить его в чистоте, мы разделим функцию you на две части. Всегда лучше иметь кучу меньших читаемых / многократно используемых функций, каждая из которых выполняет одну задачу, а не 1 superSizeMe номер 3 с большим коксом.
Получение данных
Часть 1: Получить данные из URL
func getJSONData(_ urlString: String) -> Data? {
guard
let url:URL = URL(string: urlString),
let jsonData:Data = try? Data(contentsOf: url)
else { return nil }
return jsonData
}
Часть 2. Декодирование данных во что-то, что мы можем использовать
func getGameNames() -> [String] {
let apiEndpoint = "https://www.giantbomb.com/api/games/?api_key=5094689370c2cf4ae42a2a268af0595badb1fea8&format=json&field_list=name"
guard
let data = getJSONData(apiEndpoint),
let response = try? JSONDecoder().decode(ApiGameReponse.self, from: data)
else { return [] }
//Neat little function "map" allows us to create an array names from the array of game objects.
let nameArray = response.games.map { $0.name }
return nameArray
}
Реализация
И, наконец, мы можем получить имена и использовать их по мере необходимости.
override func viewDidLoad() {
//I recommend putting this somewhere else
//Perhaps create a method called "setup()" and call it in this class's inializer.
let names = getGameNames()
print(names) //Implement the array of names as needed
}