编码给出错误“数据无法写入,因为格式不正确”

问题描述 投票:0回答:1

我有一个 API,其中基于参数的数据正在发生变化。

回应1


{
  "success": true,
  "statusCode": 200,
  "errorLst": [],
  "succcessMessage": null,
  "resultData": [
    {
      "plotSize": 1,
      "equationValue": null
    },
    {
      "plotSize": 2,
      "equationValue": "*1.5"
    },
    {
      "plotSize": 3,
      "equationValue": "*2.5"
    }
  ]
}

回应2

{
  "success": true,
  "statusCode": 200,
  "errorLst": [],
  "succcessMessage": null,
  "resultData": [
    {
      "plotSize": 4,
      "equationValue": "*4"
    },
    {
      "plotSize": 5,
      "equationValue": "*5.5"
    },
    {
      "plotSize": 6,
      "equationValue": "*6.5"
    }
  ]
}

我解析 API 数据并尝试将基本模型数据转换为我的实际模式数据:

let myEndPoint = EndPoint(modelType: PlotModel.self)
self.plotModelModel = convertToModel(baseModelResponse: inner_apiResponse, endpoint: myEndPoint) as? PlotModel ?? PlotModel()

inner_apiResponse
只不过是我从API获取的数据解析为
BaseModel

我的型号如下:

struct PlotModel : Codable {
    var success : Bool?
    var statusCode : Int?
    var succcessMessage : String?
    
    var resultData : [InnerPlotData]?
    
}

struct InnerPlotData : Codable {
    var plotSize : Int?
    var equationValue : String?
}

我正在使用以下函数将基本模型转换为我的模型:

func convertToModel<T : Codable>(baseModelResponse : BaseModel, endpoint : EndPoint<T>) -> Any {
    
    do {
        let encoder = JSONEncoder()
        do {
            let jsonData = try encoder.encode(baseModelResponse)
            if let jsonString = String(data: jsonData, encoding: .utf8) {
                if let data = jsonString.data(using: .utf8) {
                    do {
                        let localModel = try JSONDecoder().decode(endpoint.modelType.self, from: data)
                        return localModel
                    } catch {
                        print("Error parsing JSON:", error)
                        return makeErrorBaseModel()
                    }
                } else {
                    print("Invalid JSON string")
                    return makeErrorBaseModel()
                }
            } else {
                return makeErrorBaseModel()
            }
        } catch let decodingError as DecodingError {
            switch decodingError {
                case .typeMismatch(_, let c), .valueNotFound(_, let c), .keyNotFound(_, let c), .dataCorrupted(let c):
                    "error.debugDescription=c===\(c.debugDescription)".printLog()
                    return makeErrorBaseModel()
            }
        } catch {
            "error.debugDescription==\(error.localizedDescription)".printLog()
            return makeErrorBaseModel()
        }
    } catch {
        return makeErrorBaseModel()
    }
    
}

我的型号如下:

struct BaseModel : Codable {
    var success : Bool?
    var statusCode : Int?
    var succcessMessage : String?
    
    var resultData : AnyCodable?
    
}

@objcMembers final class AnyCodable: NSObject, Codable {
    
    let value: Any?
    
    init(_ value: Any?) {
        self.value = value
    }
    
    required init(from decoder: Decoder) throws {
        
        let container = try decoder.singleValueContainer()
        
        if let value = try? container.decode(String.self) {
            self.value = value
        } else if let value = try? container.decode(Bool.self) {
            self.value = value
        } else if let value = try? container.decode(Int.self) {
            self.value = value
        } else if let value = try? container.decode(Double.self) {
            self.value = value
        } else if let value = try? container.decode(Float.self) {
            self.value = value
        } else if container.decodeNil() {
            self.value = nil
        } else if let value = try? container.decode([String: AnyCodable].self) {
            self.value = value.mapValues { $0.value }
        } else if let value = try? container.decode([AnyCodable].self) {
            self.value = value.map { $0.value }
        }  else {
            throw DecodingError.dataCorruptedError(
                in: container,
                debugDescription: "Invalid value cannot be decoded"
            )
        }
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch value {
            case let bool as Bool:
                try container.encode(bool)
            case let int as Int:
                try container.encode(int)
            case let float as Float:
                try container.encode(float)
            case let double as Double:
                try container.encode(double)
            case let string as String:
                try container.encode(string)
            case let array as [Any?]:
                try container.encode(array.map { AnyCodable($0) })
            case let dictionary as [String: Any?]:
                try container.encode(dictionary.mapValues { AnyCodable($0) })
            case let encodable as Encodable:
                try encodable.encode(to: encoder)
            default:
                let context = EncodingError.Context(codingPath: container.codingPath, debugDescription: "AnyEncodable value cannot be encoded")
                throw EncodingError.invalidValue(value ?? "InvalidValue", context)
        }
    }
}

响应 2 工作正常,但是响应 1 给出错误,如下所示:

error.debugDescription==The data couldn’t be written because it isn’t in the correct format.

let jsonData = try encoder.encode(baseModelResponse)
行抛出异常。

为什么会发生这种情况以及如何解决?

要检查的最少代码

https://wetransfer.com/downloads/08ebea0e519f58023444c36727e4afdc20240820150159/adf188


根据vadian进一步检查后,我发现在

func encode
中,我得到如下异常。

invalidValue("InvalidValue", Swift.EncodingError.Context(codingPath: [CodingKeys(stringValue: "resultData", intValue: nil), _JSONKey(stringValue: "索引 0", intValue: 0), _JSONKey(stringValue: "equationValue" ,intValue:nil)],debugDescription:“无法编码任何Encodable值”,underlyingError:nil))

但是

equationValue
是模型中提到的 String 类型

json swift encode jsonencoder
1个回答
0
投票

失败的值是:

  "equationValue": null

您忘记附上案例:

case nil:
    try container.encodeNil()
© www.soinside.com 2019 - 2024. All rights reserved.