Search code examples
jsonswiftjson-deserializationswift4

Swift 4 json decoder error flickr


I am trying out the new JSONDecoder() in swift 4 and am trying to parse the following flickr API response : (https://api.flickr.com/services/rest/?api_key=api_key&method=flickr.photos.search&format=json&per_page=25&text=hello&nojsoncallback=1). However I get an error saying that "error processing json data: The data couldn’t be read because it isn’t in the correct format." However the data seems to be in the correct format to me. Am I doing anything wrong?

            let dataTask = session.dataTask(with: urlRequest) { (data, response, error) in
                if let error = error {
                    print("json error: \(error.localizedDescription)")
                    return
                } else if let data = data {
                    print(response)
                    do {
                        let decoder = JSONDecoder()
                        print(data)
                        let flickrPhotos = try decoder.decode(FlickrImageResult.self, from: data)
                    } catch {
                        dump(data)
                        print("json error: \(error.localizedDescription)")
                    }
                }
            }
            dataTask.resume()

My data models are

struct FlickrImageResult : Codable {
     var photos : FlickrPhoto? = nil

}

struct FlickrPhoto : Codable {
    var photo : [FlickrURLs]? = nil
 }

struct FlickrURLs: Codable {
    var id : String? = nil
    var owner: String? = nil
    var secret: String? = nil
    var server: String? = nil
    var farm: String? = nil
}

I changed the number of images requested to 2 and Printing out the data returns Optional({"photos":{"page":1,"pages":120197,"perpage":2,"total":"240393","photo":[{"id":"36729752762","owner":"152440263@N02","secret":"e62ba3e18b","server":"4432","farm":5,"title":"Hello there","ispublic":1,"isfriend":0,"isfamily":0},{"id":"36729384952","owner":"141041947@N06","secret":"bc0e5af630","server":"4380","farm":5,"title":"POST\ud83d\udd25 #891 | Hello Tuesday | Krescendo","ispublic":1,"isfriend":0,"isfamily":0}]},"stat":"ok"})


Solution

  • The only problem with your model is that farm is actually an Int. Here's a more complete version of your model accoirding to the docs (https://www.flickr.com/services/api/flickr.photos.search.html):

    struct FlickrImageResult: Codable {
        let photos : FlickrPagedImageResult?
        let stat: String
    }
    
    struct FlickrPagedImageResult: Codable {
        let photo : [FlickrURLs]
        let page: Int
        let pages: Int
        let perpage: Int
        let total: String
    }
    
    struct FlickrURLs: Codable {
        let id : String
        let owner: String
        let secret: String
        let server: String
        let farm: Int
        // let title: String
        // If needed, camel-case and use CodingKeys enum
        //let ispublic: Int
        //let isfriend: Int
        //let isfamily: Int
    }
    
    let jsonData = """
    {
      "photos": {
        "page": 1,
        "pages": 13651,
        "perpage": 25,
        "total": "341263",
        "photo": [
          {
            "id": "36499638920",
            "owner": "55126206@N07",
            "secret": "7e82dee0ba",
            "server": "4346",
            "farm": 5,
            "title": "[BREATHE]-Ririko,Sayaka&Chiyoko",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
          },
          {
            "id": "36724435032",
            "owner": "92807782@N04",
            "secret": "6d830d4a75",
            "server": "4354",
            "farm": 5,
            "title": "Serendipity Designs @ SWANK August 2017",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
          },
          {
            "id": "36087089863",
            "owner": "152685136@N08",
            "secret": "a4a3f2fe0a",
            "server": "4365",
            "farm": 5,
            "title": "Hello Kitty Scooter",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
          },
          {
            "id": "36086949593",
            "owner": "151818203@N02",
            "secret": "fc1207d373",
            "server": "4334",
            "farm": 5,
            "title": "Hip, Hip! It's Chip!",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
          },
          {
            "id": "36498504410",
            "owner": "148300038@N02",
            "secret": "5c7f6ff3e1",
            "server": "4391",
            "farm": 5,
            "title": "Hello Kotti",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
          }
        ]
      },
      "stat": "ok"
    }
    """.data(using: .utf8)!
    
    let flickrPhotos = try! JSONDecoder().decode(FlickrImageResult.self, from: jsonData)
    print(flickrPhotos)
    


    P.S: The message error processing json data: The data couldn’t be read because it isn’t in the correct format. is the localized error message, use print(error) instead of print(errorlocalizedDescription) to obtain all the error data available (in your case, it will print that there's an issue when trying to decode the farm key).