Ios JSON解码错误弹出,不知道还有什么可以尝试

Ios JSON解码错误弹出,不知道还有什么可以尝试,ios,json,swift,Ios,Json,Swift,伙计们,我真的非常感谢大家对JSON解码的帮助。我正在尝试从以下链接获取API: 我可能犯了一些非常业余的错误。第一次在这里上传问题。我需要帮助 这是我的数据管理员 protocol NewsManagerDelegate { func didUpdateNews(news: NewsModel) } import Foundation struct NewsManager{ var delegate: NewsManagerDelegate?

伙计们,我真的非常感谢大家对JSON解码的帮助。我正在尝试从以下链接获取API: 我可能犯了一些非常业余的错误。第一次在这里上传问题。我需要帮助

这是我的数据管理员

protocol NewsManagerDelegate {
    func didUpdateNews(news: NewsModel)
}
import Foundation

struct NewsManager{
    
    
    var delegate: NewsManagerDelegate?
    
    let url = "https://newsapi.org/v2/top-headlines?apiKey=a16b15f863454928804e218705d0f019"
    
    
    func fetchNews(_ countryName: String){
        let newsUrlString = "\(url)+&country=\(countryName)"
        performRequest(newsUrlString)
    }
    
    func performRequest(_ urlString: String){
        if let url = URL(string: urlString){
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, response, error) in
                if error != nil {
                    print("networking error \(error!)")
                    return
                }
                
                if let safeData = data{
                    if let news = parseJSON(safeData){
                        delegate?.didUpdateNews(news: news)
                }
            }
            }
            task.resume()
        }
    }
    
    func parseJSON(_ newsData: Data) -> NewsModel?{
        do{
            let decodedData = try JSONDecoder().decode(NewsData.self, from: newsData)
            let sourceName = decodedData.articles[5].source.name
            let titleName = decodedData.articles[5].title
            let linkToImage = decodedData.articles[5].urlToImage
            let news = NewsModel(sourceName: sourceName, titleName: titleName, linkToImage: linkToImage ) 
            return news
        }catch{
            print(error)
            return nil
        }
        
    }
    
    
    
    
    
}
还有我的数据

import Foundation

struct NewsData: Codable {
    let totalResults: Int
    let articles: [Articles]

}

struct Articles: Codable{
    let author: String?
    let title: String
    let description: String
    let urlToImage: String
    let source: Source
    
}

struct Source: Codable{
    let name: String
}
我收到这个错误

valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "articles", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "description", intValue: nil)], debugDescription: "Expected String value but found null instead.", underlyingError: nil))
我试着让一些常量成为可选的,但是在那之后就没有任何信息显示了

文章-说明 “应为字符串值,但改为null。”

改变

let description: String

文章-说明 “应为字符串值,但改为null。”

改变

let description: String


它说第一个值没有值,你能把你得到的json响应发布出来吗。另一种可能是json响应的顺序与解码的顺序不同

您可以将描述更改为可选的,因为这样可以解决问题,但是您没有描述,因此无法完全解决问题

let description: String?

它说第一个值没有值,你能把你得到的json响应发布出来吗。另一种可能是json响应的顺序与解码的顺序不同

您可以将描述更改为可选的,因为这样可以解决问题,但是您没有描述,因此无法完全解决问题

let description: String?

我只需将属性名称更改为
articlescription
,并将其设置为可选。如果要分析发布日期,只需将decoder
dateDecodingStrategy
属性设置为
.iso8601
。此外,您没有正确构建url。撰写url时,应始终使用
URLComponents
,并将url属性类型从
String
更改为
url

struct Root: Codable {
    let status: String
    let totalResults: Int
    let articles: [Article]
}



操场测试:

func fetchNews(_ countryCode: String) {
    var urlComponents = URLComponents()
    urlComponents.scheme = "https"
    urlComponents.host = "newsapi.org"
    urlComponents.path = "/v2/top-headlines"
    urlComponents.queryItems = [.init(name: "apiKey", value: "a16b15f863454928804e218705d0f019"),
                                .init(name:"country", value: countryCode)]
    if let url = urlComponents.url {
        performRequest(url)
    }
}
func performRequest(_ url: URL) {
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data else {
            print("networking error", error ?? "nil")
            return
        }
        do {
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .iso8601
            let root = try decoder.decode(Root.self, from: data)
            let articles = root.articles
            for article in articles {
                print("article:", article, terminator: "\n")
            }
        } catch {
            print(error)
        }

    }.resume()
}
fetchNews("us")

这将打印:

文章:文章(来源:id:Optional(“cnn”),姓名:“cnn”),作者:Optional(“Oliver Darcy,cnn Business”),标题:“Tucker Carlson Rescross告诉我们一些特朗普支持者的重要信息-cnn”,文章描述:nil,url:,urlToImage:,发布日期:2020-11-21 16:11:00+0000,内容:nil)
文章:文章(来源:id:Optional(“今日美国”)、姓名:“今日美国”)、作者:Optional(“Joel Shannon,Grace Hauck”)、标题:“冠状病毒更新:小唐纳德·特朗普检测呈阳性;模型估计到3月美国死亡人数为471k;库莫将获得国际艾美奖-今日美国”,文章描述:Optional(“小唐纳德·特朗普对冠状病毒检测呈阳性。模型预测死亡人数会增加。此前曾发生过流感大流行期间的感恩节。最新的COVID新闻。”),url:,urlToImage:,publishedAt:2020-11-21 15:56:15+0000,内容:可选(“冠状病毒疫苗可能要到2021年的几个月后才能广泛使用。\r\nUSA今天\r\n美国周五,也就是同一周,每天新增195000多例新冠病毒-19病例,创下历史新高。...(+11662 chars])
文章:文章(来源:CBS体育),作者:可选(“”),标题:“克莱姆森对佛罗里达州的比赛在开球前推迟了几个小时,因为球队不同意是否参加CBS体育”,文章描述:可选(“克莱姆森球员对新冠病毒-19的晚阳性检测是突然推迟的原因”),url:,urlToImage:,publishedAt:2020-11-21 15:28:00+0000,内容:可选(“第4号克莱姆森和佛罗里达州将于东部时间中午在佛罗里达州塔拉哈西开始比赛,这场比赛将标志着老虎队四分卫特雷弗·劳伦斯在新冠病毒呈阳性后重返赛场……[+3139个字符])


我只需将属性名称更改为
articlescription
,并将其设置为可选。如果要解析
publishedAt
日期,则只需将decoder
dateDecodingStrategy
属性设置为
.iso8601
。此外,您没有正确构建url。您应该始终使用
URLC组件
在编写url并将url属性类型从
String
更改为
url
时:

struct Root: Codable {
    let status: String
    let totalResults: Int
    let articles: [Article]
}



操场测试:

func fetchNews(_ countryCode: String) {
    var urlComponents = URLComponents()
    urlComponents.scheme = "https"
    urlComponents.host = "newsapi.org"
    urlComponents.path = "/v2/top-headlines"
    urlComponents.queryItems = [.init(name: "apiKey", value: "a16b15f863454928804e218705d0f019"),
                                .init(name:"country", value: countryCode)]
    if let url = urlComponents.url {
        performRequest(url)
    }
}
func performRequest(_ url: URL) {
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data else {
            print("networking error", error ?? "nil")
            return
        }
        do {
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .iso8601
            let root = try decoder.decode(Root.self, from: data)
            let articles = root.articles
            for article in articles {
                print("article:", article, terminator: "\n")
            }
        } catch {
            print(error)
        }

    }.resume()
}
fetchNews("us")

这将打印:

文章:文章(来源:id:Optional(“cnn”),姓名:“cnn”),作者:Optional(“Oliver Darcy,cnn Business”),标题:“Tucker Carlson Rescross告诉我们一些特朗普支持者的重要信息-cnn”,文章描述:nil,url:,urlToImage:,发布日期:2020-11-21 16:11:00+0000,内容:nil)
文章:文章(来源:id:Optional(“今日美国”),姓名:“今日美国”),作者:Optional(“Joel Shannon,Grace Hauck”),标题:“冠状病毒更新:小唐纳德·特朗普检测呈阳性;模型估计到3月美国死亡人数为471k;库莫将获得国际艾美奖-今日美国”,文章描述:Optional(“小唐纳德·特朗普对冠状病毒检测呈阳性。模型预测死亡人数会增加。此前曾发生过流感大流行期间的感恩节。最新的冠状病毒新闻。”),url:,urlToImage:,publishedAt:2020-11-21 15:56:15+0000,内容:可选(“冠状病毒疫苗可能要到2021年的几个月后才能广泛使用。\r\nUSA今天\r\n美国周五,也就是同一周,每天新增195000多例新冠病毒-19病例,创下历史新高。...(+11662 chars])
文章:文章(来源:CBS体育),作者:可选(“”),标题:“克莱姆森对佛罗里达州的比赛在开球前推迟了几个小时,因为球队不同意是否参加CBS体育”,文章描述:可选(“克莱姆森球员对新冠病毒-19的晚阳性检测是突然推迟的原因”),url:,urlToImage:,publishedAt:2020-11-21 15:28:00+0000,内容:可选(“第4号克莱姆森州和佛罗里达州将于东部时间中午在佛罗里达州塔拉哈西市开始一场比赛