我正在尝试使用Codable解析JSON响应,但这给了我错误。 我试图从下面的堆栈溢出链接引用,但没有用。 how do I parse Any in dictionary using swift
下面是我的代码,不确定在哪里我错了。
> 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 url和关注者。 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)。
谢谢
答案 0 :(得分:2)
请学习阅读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
情况返回所有 real 错误。 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...
类,这里URL
代表NSURL
,URLRequest
代表NS(Mutable)URLRequest
答案 1 :(得分:1)
您需要
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)
因为它会崩溃