【问题标题】:Swift 4 json decoder error flickrSwift 4 json 解码器错误 flickr
【发布时间】:2018-02-07 08:22:52
【问题描述】:

我正在 swift 4 中尝试新的 JSONDecoder() 并尝试解析以下 flickr API 响应:(https://api.flickr.com/services/rest/?api_key=api_key&method=flickr.photos.search&format=json&per_page=25&text=hello&nojsoncallback=1)。但是,我收到一条错误消息,提示“处理 json 数据时出错:无法读取数据,因为它的格式不正确。”但是,数据对我来说似乎是正确的格式。我做错什么了吗?

            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()

我的数据模型是

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
}

我将请求的图像数量更改为 2 并打印出数据返回 可选({"照片":{"page":1,"pages":120197,"perpage":2,"total":"240393","photo":[{"id":"36729752762","owner ":"152440263@N02","secret":"e62ba3e18b","server":"4432","farm":5,"title":"你好","ispublic":1,"isfriend":0 ,"isfamily":0},{"id":"36729384952","owner":"141041947@N06","secret":"bc0e5af630","server":"4380","farm":5," title":"POST\ud83d\udd25 #891 | 你好星期二 | Krescendo","ispublic":1,"isfriend":0,"isfamily":0}]},"stat":"ok"})

【问题讨论】:

  • 如果您只是从 URL 响应中打印 data,它是否显示正确的 JSON 字符串?
  • 所以响应返回 200,打印数据返回 4694 字节,所以我认为那里有东西。
  • 试试print(String(bytes:data, encoding: .utf8) )看看到底有什么
  • 我就是这么做的,谢谢!它确实返回了我将其添加到问题中的正确数据。
  • 答案已更新为分页响应。

标签: json swift json-deserialization swift4


【解决方案1】:

您的模型的唯一问题是farm 实际上是Int。根据文档 (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)


PS:消息error processing json data: The data couldn’t be read because it isn’t in the correct format.是本地化错误消息,使用print(error)而不是print(errorlocalizedDescription)来获取所有可用的错误数据(在你的情况下,它会在尝试时打印出有问题解码农场密钥)。

【讨论】:

  • 您好,非常感谢您的帮助。但是,当我插入上述内容并将其放入 do catch 块中时,它仍然给我错误“无法读取数据,因为它的格式不正确。”会不会是 swift 4 的问题? do { let flickrPhotos = try JSONDecoder().decode(FlickrImageResult.self, from: jsonData) print(flickrPhotos) } catch { print(error.localizedDescription) }
  • 整个示例有效:在此处查看实时评估 swift.sandbox.bluemix.net/#/repl/59a5c3e452eabe5bb8de608f(也适用于 Playgrounds/Empty iOS 应用)
  • 非常感谢!它一定是我的项目中的东西!
  • 没关系,这是 JSON 编码问题(farm 是 Int 而不是 String)。调试时,切勿使用error.localizedDescription,而是使用print("json error: \(error)")。它将提供更多信息。
  • 您的模型的唯一问题是农场需要是一个 Int(答案已更新)。
猜你喜欢
  • 2018-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 2019-01-11
相关资源
最近更新 更多