Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected nil in JSON strings

Tags:

json

null

swift

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"
    },
    {
like image 878
Saeed Rahmatolahi Avatar asked May 01 '26 23:05

Saeed Rahmatolahi


1 Answers

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.

like image 106
vadian Avatar answered May 05 '26 06:05

vadian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!