【问题标题】:getting error message from codable struct从可编码结构中获取错误消息
【发布时间】:2017-12-24 07:28:35
【问题描述】:

我正在解码一个 JSON 结构,如果它无法解码,此时在我的错误检查中,这意味着服务器响应中缺少一个字段,我想向用户显示该字段。

解码此结构时:

struct UserResponseObject: Decodable {
let message: String
let data: User
}

这里

do {
            let responseObject = try createDecoder().decode(UserResponseObject.self, from: jsonData)
            //print("RESPONSE MESSAGE: ", responseObject.message)
            //print("GET USER DATA: ",responseObject.data)
            completion!(.success(responseObject.data))
        } catch let error as NSError {
            print("failure to decode user from JSON")
            completion!(.failure(error))
        }

如果没有字段.data,我想在catch块中返回responseObject.message中的消息。但是我不允许将响应重新解码到这个结构中。

struct ErrorObject: Decodable {
let message: String
}

当第一次解码失败时,我应该如何尝试获取消息。谢谢

【问题讨论】:

    标签: ios json rest decodable


    【解决方案1】:

    您可以通过添加更多的 catch 块来了解错误的确切性质:

    do {
        let messages = try JSONDecoder().decode(Results.self, from: data)
    } catch DecodingError.dataCorrupted(let context) {
        print(context)
    } catch DecodingError.keyNotFound(let key, let context) {
        print("Key '\(key)' not found:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch DecodingError.valueNotFound(let value, let context) {
        print("Value '\(value)' not found:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch DecodingError.typeMismatch(let type, let context) {
        print("Type '\(type)' mismatch:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch {
        print("error: ", error)
    }
    

    【讨论】:

      【解决方案2】:

      如果您的结构实现可编码,那么您最好使用 JSONEncoder 和 JSONDecoder

      struct Language: Codable {
        var name: String
        var version: Int
      }
      
      let swift = Language(name: "Swift", version: 4)
      let encoder = JSONEncoder()
      if let encoded = try? encoder.encode(swift) {
        // save `encoded` somewhere
       }
      
      if let encoded = try? encoder.encode(swift) {
      if let json = String(data: encoded, encoding: .utf8) {
       print(json)
      }
      
      let decoder = JSONDecoder()
       if let decoded = try? decoder.decode(Language.self, from: encoded) {
         print(decoded.name)
      }
      

      【讨论】:

        【解决方案3】:

        如果 json 中缺少任何字段,您应该首先将其设为可选。在你的情况下应该是,

        struct UserResponseObject: Decodable {
           let message: String? // You should decide, should it be optional or not
           let data: User? // You should decide, should it be optional or not
        }
        

        您还应该处理 do 块中的无数据情况... 因此,在您的 try-catch 块中尝试创建 UserResponseObject 对象的新实例;

        do {
                    let responseObject = try createDecoder().decode(UserResponseObject.self, from: jsonData)
                    //print("RESPONSE MESSAGE: ", responseObject.message)
                    //print("GET USER DATA: ",responseObject.data)
                    if(responseObject.data) {
                        completion!(.success(responseObject.data))
                    }
                    else {
                        completion!(.failure(//no data error handler))
                    }
                } catch let error as NSError {
                    let responseObject = UserResponseObject(message: error.localizedDescription, data: nil)
                    print("failure to decode user from JSON")
                    completion!(.failure(error))
                }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-30
          • 1970-01-01
          • 2023-04-08
          • 2023-04-11
          • 2023-03-12
          相关资源
          最近更新 更多