Я хотел бы создать функцию, которая принимает несколько параметров, а затем выводит нужные мне данные из веб-API.Очевидно, что большую часть времени мне потребуется настроить его в соответствии с вариантом использования, но просто для удовольствия я пытаюсь выяснить суперосновную функцию, которая успешно анализирует JSON, примерно как половину строк кода в функции.ниже приведена общая обработка ошибок.
Например, если я обычно использую что-то вроде
func getJSON(completionHandler: @escaping (Bool) -> ()) {
let jsonUrlString = "https://api.nytimes.com/svc/topstories/v1/business.json?api-key=f4bf2ee721031a344b84b0449cfdb589:1:73741808"
guard let url = URL(string: jsonUrlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data, err == nil else {
print(err!)
return
}
do {
let response = try
JSONDecoder().decode(TopStoriesResponse.self, from: data)
self.storyData = response.results
completionHandler(true)
} catch let jsonErr {
print("Error serializing JSON", jsonErr)
}
}.resume()
}
Только три вещи, которые будут меняться от случая к случаю (опять же, в самых базовых сценариях)) - это URL-ссылка на API, структура, которую я настроил для поиска нужных мне фрагментов данных, и массив, в который я выводил результаты после завершения запроса данных.
Могу ли я обрезатьжир на этом и сделать что-то вроде
func jsonFetcher(apiLink: String, structToDecode: String, arrayThatHoldsResponse: [String], completionHandler: @escaping (Bool) -> ()) {
let jsonUrlString = apiLink
guard let url = URL(string: jsonUrlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data, err == nil else {
print(err!)
return
}
do {
let response = try
JSONDecoder().decode(structToDecode, from: data)
arrayThatHoldsResponse = response.results
completionHandler(true)
} catch let jsonErr {
print("Error serializing JSON", jsonErr)
}
}.resume()
}
Я просто не уверен насчет типов данных structToDecode
и arrayThatHoldsResponse
(в приведенном выше примере функции я просто использовал String
в качестве заполнителя), предполагая, что они выглядят как
Структура (ы)
struct TopStoriesResponse: Decodable {
let status: String
let results: [Story]
}
struct Story: Decodable {
let title: String
let abstract: String
let url: String
let multimedia: [Multimedia]
private enum CodingKeys: String, CodingKey {
case title
case abstract
case url
case multimedia
}
init(from decoder:Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
title = try container.decode(String.self, forKey: .title)
abstract = try container.decode(String.self, forKey: .abstract)
url = try container.decode(String.self, forKey: .url)
multimedia = (try? container.decode([Multimedia].self, forKey: .multimedia)) ?? []
}
}
Массив
var storyData = [Story]()
Таким образом, я могу просто позвонить
jsonFetcher(apiLink: link, structToDecode: myStruct, arrayThatHoldsResponse: myArray, completionHandler: <#T##(Bool) -> ()#>)
Tспасибо за любую помощь!