Unexpected nil in JSON strings

岁酱吖の 提交于 2019-12-11 05:21:37

问题


I parse JSON in my application and some of the JSONs have nil values which I handled. However, the app still shows me the error that JSON contains nil values. My code:

struct Response : Decodable {
let articles: [Article]
 }

struct Article: Decodable {

let title: String
let description : String
let url : String
let urlToImage : String
}
URLSession.shared.dataTask(with: url) { (data, response, error) in
     guard let data = data else { return }
     do {
     let article =  try JSONDecoder().decode(Response.self , from : data)
     for i in 0...article.articles.count - 1 {
         if type(of: article.articles[i].title) == NSNull.self {
             beforeLoadNewsViewController.titleArray.append("")
         } else {
             beforeLoadNewsViewController.titleArray.append(article.articles[i].title)
         }
if type(of : article.articles[i].urlToImage) == NSNull.self {
                beforeLoadNewsViewController.newsImages.append(newsListViewController.newsImages[newsListViewController.newsIndex])

                    } else {


                    let url = URL(string: article.articles[i].urlToImage ?? "https://static.wixstatic.com/media/b77fe464cfc445da9003a5383a3e1acf.jpg")


                    let data = try? Data(contentsOf: url!)

                    if url != nil {

                    //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
                        let img = UIImage(data: data!)
                    beforeLoadNewsViewController.newsImages.append(img!)

                    } else {
                beforeLoadNewsViewController.newsImages.append(newsListViewController.newsImages[newsListViewController.newsIndex])

                        }

This is the error running the app:

FC91DEECC1631350EFA71C9C561D).description], debugDescription: "Expected String value but found null instead.", underlyingError: nil))

Note:

This JSON works with other urls that don't have nil values.

and here is the json

{
    "status": "ok",
    "source": "entertainment-weekly",
    "sortBy": "top",
    "articles": [
    {
        "author": null,
        "title": "Hollywood's Original Gone Girl",
        "description": null,
        "url": "http://mariemcdonald.ew.com/",
        "urlToImage": null,
        "publishedAt": null
    },
    {
        "author": "Samantha Highfill",
        "title": "‘Supernatural’: Jensen Ackles, Jared Padalecki say the boys aren’t going ‘full-mope’",
        "description": "",
        "url": "http://ew.com/tv/2017/10/18/supernatural-jensen-ackles-jared-padalecki-season-13/",
        "urlToImage": "http://ewedit.files.wordpress.com/2017/10/supernatural-season-13-episode-1.jpg?crop=0px%2C0px%2C2700px%2C1417.5px&resize=1200%2C630",
        "publishedAt": "2017-10-18T17:23:54Z"
    },
    {

回答1:


The error is quite clear. JSONDecoder maps NSNull to nil so the decoder throws an error if it's going to decode a nil value to a non-optional type.

The solution is to declare all affected properties as optional.

let title: String
let description : String?
let url : String
let urlToImage : String?

or customize the decoder to replace nil with an empty string.

And because JSONDecoder maps NSNull to nil the check if ... == NSNull.self { is useless.

Edit:

Don't use ugly C-style index based loops use

 let response =  try JSONDecoder().decode(Response.self , from : data)
 for article in response.articles {
      beforeLoadNewsViewController.titleArray.append(article.title)
 }

PS: But why for heaven's sake do you map the article instance to – apparently – separate arrays? You got the Article instances which contain everything related to one article respectively.




回答2:


I am sorry, I cannot comment yet. But why don't you test for "null" the way, you did at the URLSession data check, with the guard-statement?

It would then look like:

guard let title = article.articles[i].title else {
    beforeLoadNewsViewController.titleArray.append("")
    return
}
beforeLoadNewsViewController.titleArray.append(title)

You try to parse a JSON structure here, in case the JSON structure would not fit to your needs, you still expect it to have the according attributes.

Could you also provide your JSON structure and how your decoding

try JSONDecoder().decode(Response.self , from : data)

looks like?



来源:https://stackoverflow.com/questions/46795003/unexpected-nil-in-json-strings

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!