[英]Parsing JSON response using Codable gives error in swift
我正在嘗試使用Codable解析JSON響應,但它給了我錯誤。 我試圖從下面的堆棧溢出鏈接引用,但沒有工作。 如何使用swift解析字典中的Any
下面是我的代碼,不知道我在哪里錯了。
> enum JSONError: String,Error {
> case NoData = "ERROR: no data"
> case ConversionFailed = "ERROR: conversion from JSON failed"
> }
struct Owner : Decodable {
let full_name : String
let html_url:String
let follower:follower
}
struct follower : Decodable {
let followers_url : String
}
func jsonParser() {
let urlPath = "https://api.github.com/search/repositories?q=language:ruby&sort=stars&order=desc"
guard let endpoint = NSURL(string: urlPath) else {
print("Error creating endpoint")
return
}
let request = NSMutableURLRequest(url:endpoint as URL)
URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
do {
guard let data = data else {
throw JSONError.NoData
}
let jsonResponse = try JSONSerialization.jsonObject(with:
data)
let entries = try! JSONDecoder().decode([Owner].self, from: jsonResponse as! Data)
print(jsonResponse)
} catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}.resume()
}
我需要從此響應中獲取3個信息 - 全名,html網址和關注者。 鏈接web api
https://api.github.com/search/repositories?q=language:ruby
請最新看一下代碼。
以下是錯誤消息:
'__NSDictionaryI'(0x102965a98)到'NSData'(0x102964580)。 2019-02-09 16:17:42.062971 + 0530 PhotoViewwer [13342:259997]無法將'__NSDictionaryI'(0x102965a98)類型的值轉換為'NSData'(0x102964580)。
謝謝
請學習閱讀JSON。 這很容易。 只有兩種集合類型,array( []
)和dictionary( {}
)
你的結構是錯誤的。
在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結構成員
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...
類,如果有本機等價物,這里NSURL
URL
和NS(Mutable)URLRequest
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()
}
你需要
func jsonParser() {
let urlPath = "https://api.github.com/search/repositories?q=language:ruby&sort=stars&order=desc"
guard let endpoint = NSURL(string: urlPath) else {
print("Error creating endpoint")
return
}
let request = NSMutableURLRequest(url:endpoint as URL)
URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
do {
let dec = JSONDecoder()
dec.keyDecodingStrategy = .convertFromSnakeCase
let entries = try dec.decode(Root.self, from:data!)
print(entries)
} catch {
print(error)
}
}.resume()
}
struct Root : Decodable {
let items:[Item]
}
struct Owner: Codable {
let login: String
let id: Int
let nodeId: String
let avatarUrl: String
let gravatarId: String
let url, htmlUrl, followersUrl: String
let followingUrl, gistsUrl, starredUrl: String
let subscriptionsUrl, organizationsUrl, reposUrl: String
let eventsUrl: String
}
struct Item: Codable {
let fullName : String
let htmlUrl:String
let owner: Owner
}
您不應該在此處轉換對數據的響應
from: jsonResponse as! Data)
因為它會崩潰
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.