Error fetching interesting photos: invalidJSONData

I was able to get the JSON data to show in console initially but later in the chapter when it has me parse the data I keep getting an error instead of the photo count that it’s supposed to show. Code below. Any ideas what I’ve done wrong?

This is my FlickrAPI.swift file:

import Foundation

enum FlickrError: Error {
case invalidJSONData

enum Method: String {
case interestingPhotos = “flickr.interestingness.getList”

struct FlickrAPI {

private static let baseURLString = ""
private static let apiKey = "a6d819499131071f158fd740860a5a88"

private static let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    return formatter

private static func flickrURL(method: Method, parameters: [String:String]?) -> URL {
    var components = URLComponents(string: baseURLString)!
    var queryItems = [URLQueryItem]()
    let baseParams = [
        "method": method.rawValue,
        "format": "json",
        "nojsoncallback": "1",
        "api_key": apiKey
    for (key, value) in baseParams {
        let item = URLQueryItem(name: key, value: value)
    if let additionalParams = parameters {
        for (key, value) in additionalParams {
            let item = URLQueryItem(name: key, value: value)
    components.queryItems = queryItems
    return components.url!

private static func photo(fromJSON json: [String : Any]) -> Photo? {
        let photoID = json["id"] as? String,
        let title = json["title"] as? String,
        let dateString = json["dateTaken"] as? String,
        let photoURLString = json["url_h"] as? String,
        let url = URL(string: photoURLString),
        let dateTaken = dateString) else {
            //don't have enough information to construct a photo
            return nil
    return Photo(title: title, photoID: photoID, remoteURL: url, dateTaken: dateTaken)

static var interestingPhotosURL: URL {
    return flickrURL(method: .interestingPhotos, parameters: ["extra": "url_h,date_taken"])

static func photos(fromJSON data: Data) -> PhotosResult {
    do {
        let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
            let jsonDictionary = jsonObject as? [AnyHashable:Any],
            let photos = jsonDictionary["photos"] as? [String:Any],
            let photosArray = photos["photo"] as? [[String:Any]] else {
                //the json strucutre doesn't match our expectations
                return .failure(FlickrError.invalidJSONData)
        var finalPhotos = [Photo]()
        for photoJSON in photosArray {
            if let photo = photo(fromJSON: photoJSON) {
        if finalPhotos.isEmpty && !photosArray.isEmpty {
            //we weren't able to parse any of the photos
            //maybe the json format for the photos has changed
            return .failure(FlickrError.invalidJSONData)
        return .success(finalPhotos)
} catch let error {
    return .failure(error)


Digging deeper into this, I’ve noticed that the JSON data I’m getting back from Flickr doesn’t match exactly with the parameters in my code. Here’s an example of what I get from Flickr:

photo = {
farm = 5;
id = 36161991222;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = “113231763@N07”;
secret = 405786f8d2
server = 4389
title = “La Lumo\U00e8re do sour (the code is longer but you get the idea)”

So I don’t have datetaken or url_h which is what my function is trying to pull.

Annnnd I’m an idiot.

I was missing an “s” on “extras” in the interestingPhotosURL function. Ugh.

the problem is in private static func photo, at line let dateString = json[“dateTaken”] as? String, you must replace “dateTaken” with “datetaken”


I elimininated any reference to dateTaken including “datetaken” in “extras”, since it was not present in the jsonObject, and I got an image.

This fixed it for me. Thanks