【问题标题】:Swift : The data couldn’t be read because it isn’t in the correct formatSwift:无法读取数据,因为它的格式不正确
【发布时间】:2019-07-28 13:25:30
【问题描述】:

我尝试使用 Alamofire 调用 POST Api,但它向我显示格式不正确的错误。

这是我的 JSON 响应:

[
  {
    "_source": {
      "nome": "LOTERIAS BELEM",
      "endereco": "R DO COMERCIO, 279",
      "uf": "AL",
      "cidade": "BELEM",
      "bairro": "CENTRO"
    },
    "_id": "010177175"
  },
  {
    "_source": {
      "nome": "Bel Loterias"
    },
    "_id": "80224903"
  },
  {
    "_source": {
      "nome": "BELLEZA LOTERIAS",
      "endereco": "R RIVADAVIA CORREA, 498",
      "uf": "RS",
      "cidade": "SANTANA DO LIVRAMENTO",
      "bairro": "CENTRO"
    },
    "_id": "180124986"
  }
]

class Album: Codable {
    var _source :  [_source]

}

class _source: Codable {
    var nome :  String
    var endereco : String
    var uf : String
    var cidade : String
    var bairro : String
}

var arrList = [Album]()

这就是我尝试使用 Alamofire 解码的方式。

func request() {

        let urlString = URL(string: "My Url")
      //  Alamofire.request(url!).responseJSON {(response) in

        Alamofire.request(urlString!, method: .post, parameters: ["name": "belem"],encoding: JSONEncoding.default, headers: nil).responseJSON {
            (response) in

            switch (response.result) {
            case .success:
                if let data = response.data {
                    do {
                        let response = try JSONDecoder().decode([Album].self, from: data)
                        DispatchQueue.main.async {
                             self.arrList = response
                        }
                    }
                    catch {
                        print(error.localizedDescription)
                    }
                }
            case .failure( let error):
                print(error)
            }
       }
 }

【问题讨论】:

  • 从不在解码 JSON 时打印 error.localizedDescription。打印error,它会告诉你到底出了什么问题。并停止使用那些丑陋的 objective-c-ish 下划线字符。 Swift 中的结构以大写字母开头!

标签: json swift alamofire jsondecoder


【解决方案1】:

只是您的Album 模型不正确。

struct Album: Codable {
    var source : Source
    var id     : String

    enum CodingKeys: String, CodingKey {
        case source = "_source"
        case id = "_id"
    }
}

struct Source: Codable {
    var nome     : String
    var endereco : String?
    var uf       : String?
    var cidade   : String?
    var bairro   : String?
}

如果您完全不想要_id,那么只需删除相关部分即可。
至于你的Alamofire相关代码,那部分很好。


显着改进:

  • 通过自定义 CodingKeys 以用于键映射,避免在模型中使用下划线变量名称
  • 类型名称应始终以大写字母开头(所以_sourceSource
    • 同样,变量名应始终以小写字母开头
  • 使一些变量可选(基于您更新的响应)
    • 保持变量非可选意味着它必须出现在要创建的模型的响应中
    • 将变量设为可选意味着响应中可能存在也可能不存在键,并且它不存在不会阻止创建模型

【讨论】:

  • 好的,我试试这个,但 keyNotFound(CodingKeys(stringValue: "_source", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"_source\", intValue: nil) (\"_source\").", underlyingError: nil)) 显示错误
  • @KrunalNagvadia 分享您的 json 响应。似乎某些对象缺少“_source”。无论如何,在你的 alamofire 请求函数中与 print(try? JSONSerialization.jsonObject(with: data, options: [])) 分享日志
  • @KrunalNagvadia 嗯...第 7 个对象只有“nome”键,其余的都没有。我们必须将 Source 中的其余部分设为可选。
  • @KrunalNagvadia 检查更新的答案。稍后会添加解释。
【解决方案2】:

我想推荐你使用 json4swift.com。你只需要复制你的 json 并粘贴到那里。它会自动从你的 json 创建模态结构或类。

回到您的问题,您的班级相册没有 [_source] 数组。这就是您收到以下错误“无法读取数据,因为它的格式不正确”的原因。

尝试以下给定的专辑类格式,

class Album: Codable
{ 
  var source: Source?
  var id: String?
}

请尽量避免在 Swift 中使用下划线。

【讨论】:

    猜你喜欢
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2018-12-25
    • 2020-03-11
    • 1970-01-01
    • 2016-10-15
    相关资源
    最近更新 更多