Пожалуйста, научитесь читать JSON.Это довольно легко.Существует только два типа коллекций, массив ([]
) и словарь ({}
)
Ваши структуры неверны.
В корневом словаре JSON есть массив словарейдля ключа items
.
В каждом словаре есть ключи full_name
и owner
( здесь - это структура Owner
).
Словарь для ключа follower
существует не существует.
Эти структуры правильно представляют JSON
struct Response : Decodable {
let items : [Item]
}
struct Item : Decodable {
let fullName : String
let owner : Owner
}
struct Owner : Decodable {
let htmlUrl : URL // URL strings can be decoded directly into URL
let followersUrl : URL
}
Добавьте обработчик завершения в вашу функцию и используйте перечисление в качестве типа результата.Случай failure
возвращает все реальные ошибки.URLRequest
является избыточным.Просто передайте URL.Линия JSONSerialization
бессмысленна.
Стратегия convertFromSnakeCase
преобразует snake_cased ключи в camelCased struct членов
enum Result {
case success(Response), failure(Error)
}
func jsonParser(completion: @escaping (Result) -> Void) {
let endpoint = URL(string:"https://api.github.com/search/repositories?q=language:ruby&sort=stars&order=desc")!
URLSession.shared.dataTask(with: endpoint) { (data, response, error) in
if let error = error { completion(.failure(error)); return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let entries = try decoder.decode(Response.self, from: data!)
completion(.success(entries))
} catch {
completion(.failure(error))
}
}.resume()
}
и вызывает его
jsonParser { result in
switch result {
case .success(let entries) : print(entries)
case .failure(let error) : print(error)
}
}
В основном никогда не используйте NS...
классы, если есть собственные эквиваленты, здесь URL
для NSURL
и URLRequest
для NS(Mutable)URLRequest
Редактировать:
В Swift 5 синтаксис становится более удобным, если использовать собственный тип Result
.Он может конвертировать бросающее выражение
enum Result {
case success(Response), failure(Error)
}
func jsonParser(completion: @escaping (Result<Response,Error>) -> Void) {
let endpoint = URL(string:"https://api.github.com/search/repositories?q=language:ruby&sort=stars&order=desc")!
URLSession.shared.dataTask(with: endpoint) { (data, response, error) in
if let error = error { completion(.failure(error)); return }
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
completion(Result{ try decoder.decode(Response.self, from: data!) })
}.resume()
}