【问题标题】:JSON could not be serialized because of error: The data couldn’t be read because it isn’t in the correct format.[Swift 4.2]JSON 由于错误而无法序列化:无法读取数据,因为它的格式不正确。[Swift 4.2]
【发布时间】:2020-07-08 00:08:27
【问题描述】:

如何使用 Alamofire 5 在 HTTP 正文中发送带有嵌套对象(如字典数组)的 POST 请求?我无法通过 JSONSerialization 将对象转换为正确格式,不知道下一步该怎么做?

我的 JSON 对象需要作为参数传递

{
"OrderProducts": [
        {
            "ProductId": 2,
            "PrimaryModifierId": 20,
            "SecondaryModifierId": 13,
            "ProductBasePrice": 100,
            "ProductDiscount": 10,
            "Quantity": 3,
            "Total": 270
        },
        {
            "ProductId": 3,
            "PrimaryModifierId": 1,
            "SecondaryModifierId": 6,
            "ProductBasePrice": 120,
            "ProductDiscount": 10,
            "Quantity": 2,
            "Total": 216
        }
    ],
    "OrderDeals": [
        {
            "DealId": 1,
            "DealPrice": 2299,
            "Quantity": 3,
            "Total":6897
        },
        {
            "DealId": 2,
            "DealPrice": 1299,
            "Quantity": 1,
            "Total":1299
        }
    ],
   "OrderDetail": {
            "UserId": 5,
            "PaymentMethodId": 1,
            "OrderPromoCodeId": 1,
            "AddressId": 12,
            "ProductTotal": 700,
            "DealTotal": 500,
            "SubTotal": 1200,
            "ShippingCharges": 300,
            "Tax": 100,
            "TotalPrice": 1600
        },
    "PaymentDetail": {
            "LastFour": 1234,
            "TransactionReference": "sad",
            "TransactionStatus": "Aproved"
        }

}

我的发帖请求功能

 func OrderCreate(OrderProduct:[[String:Any]] , PaymentDetail:[String:Any], OrderDetail:[String:Any], OrderDeals:[[String:Any]],  completionHandler:@escaping (_ success:OrderCreateModelClass.OrderCreateModel?, Error?) -> ()){

    let header : HTTPHeaders = [
                Api.Params.contentType:Api.Params.applicationJSON,
               Api.Params.authorization:requestManager.instance.getToken!
            ]

    let params : [String:Any] = [
        "OrderProducts" : OrderProduct ,
        "OrderDeals" : OrderDeals,
        "OrderDetail" : OrderDetail,
        "PaymentDetail" : PaymentDetail
    ]

    manager.request(Api.CONSTANTS_METHODS.ORDER_CREATE_API, method: .post, parameters: params, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in
                    switch response.result {
                    case .success(let validResponse):
                        guard let res = validResponse as? [String:Any] else {return}
                        if ((res["flag"] as? Int) != nil) {
                        let data = try! JSONSerialization.data(withJSONObject: validResponse.self, options: [])
                            let resultObject = try! JSONDecoder().decode(OrderCreateModelClass.OrderCreateModel.self, from: data)
                        completionHandler(resultObject,nil)
                        } else {
                        completionHandler(nil,nil)
                        }
                    case .failure(let error):
                        print("FailedNot")
                        switch (response.response?.statusCode) {
                        case 404:
                            print("not Found")
                        case 401:
                            print("unauthorized")
                        case 408:
                            print("request timeout")
                        case 406:
                            print("Unable to format response according to Accept header")
                        completionHandler(nil,error)
                        default:
                            print(error.localizedDescription)
                        }
                }
        }
}

我遇到的错误

我的格式错误的 Json 对象看起来像这样(转换后打印)

已编辑:

在Dilan的解决方案之后Func看起来像这样(但仍然给出相同的错误)

func OrderCreate(OrderProduct:[[String:Any]] , PaymentDetail:[String:Any], OrderDetail:[String:Any], OrderDeals:[[String:Any]],  completionHandler:@escaping (_ success:OrderCreateModelClass.OrderCreateModel?, Error?) -> ()){

    let header : HTTPHeaders = [
                Api.Params.contentType:Api.Params.applicationJSON,
               Api.Params.authorization:requestManager.instance.getToken!
            ]

    var products = [Parameters]()
    var deals = [Parameters]()

    OrderProduct.forEach { (product) in
            let item:Parameters = [
            "ProductId": product["ProductId"] as? Int ?? 0,
            "PrimaryModifierId": product["PrimaryModifierId"] as? Int ?? 0,
            "SecondaryModifierId": product["SecondaryModifierId"] as? Int ?? 0,
            "ProductBasePrice": product["ProductBasePrice"] as? Double ?? 0,
            "ProductDiscount": product["ProductDiscount"] as? Double ?? 0,
            "Quantity": product["Quantity"] as? Double ?? 0,
            "Total": product["Total"] as? Double ?? 0
        ]
        products.append(item)
    }

    OrderDeals.forEach { (deal) in
        let item : Parameters = [
            "DealId" : deal["DealId"] as? Int ?? 0,
            "DealPrice" : deal["DealPrice"] as? Int ?? 0,
            "Quantity" : deal["Quantity"] as? Int ?? 0,
            "Total" : deal["Total"] as? Int ?? 0
        ]
        deals.append(item)
    }

    let paymentDetail : Parameters = [

        "LastFour" : PaymentDetail["LastFour"] as? Int ?? 0,
        "TransactionReference" : PaymentDetail["TransactionReference"] as? Int ?? 0,
        "TransactionStatus" : PaymentDetail["TransactionStatus"] as? Int ?? 0
    ]

    let orderDetail : Parameters = [
        "UserId" : OrderDetail["UserId"] as? Int ?? 0,
        "PaymentMethodId" : OrderDetail["PaymentMethodId"] as? Int ?? 0,
        "OrderPromoCodeId" : OrderDetail["OrderPromoCodeId"] as? Int ?? 0,
        "AddressId" : OrderDetail["AddressId"] as? Int ?? 0,
        "ProductTotal" : OrderDetail["ProductTotal"] as? Int ?? 0,
        "DealTotal" : OrderDetail["DealTotal"] as? Int ?? 0,
        "SubTotal" : OrderDetail["SubTotal"] as? Int ?? 0,
        "ShippingCharges" : OrderDetail["ShippingCharges"] as? Int ?? 0,
        "Tax" : OrderDetail["Tax"] as? Int ?? 0,
        "TotalPrice" : OrderDetail["TotalPrice"] as? Int ?? 0
    ]

    let params : [String:Any] = [
        "OrderProducts" : products ,
        "OrderDeals" : deals,
        "OrderDetail" : orderDetail,
        "PaymentDetail" : paymentDetail
    ]



    manager.request(Api.CONSTANTS_METHODS.ORDER_CREATE_API, method: .post, parameters: params, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in


                    switch response.result {
                    case .success(let validResponse):
                        guard let res = validResponse as? [String:Any] else {return}
                        if ((res["flag"] as? Int) != nil) {
                        let data = try! JSONSerialization.data(withJSONObject: validResponse.self, options: [])
                            let resultObject = try! JSONDecoder().decode(OrderCreateModelClass.OrderCreateModel.self, from: data)
                        completionHandler(resultObject,nil)
                        } else {
                        completionHandler(nil,nil)
                        }
                    case .failure(let error):
                        print("FailedNot")
                        switch (response.response?.statusCode) {
                        case 404:
                            print("not Found")
                        case 401:
                            print("unauthorized")
                        case 408:
                            print("request timeout")
                        case 406:
                            print("Unable to format response according to Accept header")
                        completionHandler(nil,error)
                        default:
                            print(error.localizedDescription)
                        }
                }
        }
}

【问题讨论】:

  • 为什么是OrderProduct:[[String:Any]]?检查参数中的OrderProduct:[String:Any]
  • @DilanAnuruddha 因为 OrderProduct 和 OrderDeal 是字典数组 .. 你可以在评论上方看到它打印的对象图像

标签: ios json swift post alamofire


【解决方案1】:

在 alamofire 中我们不能直接转换这些类型的 json(带有嵌套数组)。你应该将它的对象转换为参数从内部到外部..

在将 OrderProduct 添加到 params 之前,您需要循环 OrderProduct 数组并创建 Alamofire Parameter objects 数组,然后您可以将该数组添加到您的 param 数组中,

var products:[Parameters] = [:]

OrderProduct.forEach { (product) in

    let item:Parameters = [
        "ProductId": product["ProductId"] as? Int ?? 0,
        "PrimaryModifierId": product["PrimaryModifierId"] as? Int ?? 0,
        "SecondaryModifierId": product["SecondaryModifierId"] as? Int ?? 0,
        "ProductBasePrice": product["ProductBasePrice"] as? Double ?? 0,
        "ProductDiscount": product["ProductDiscount"] as? Double ?? 0,
        "Quantity": product["Quantity"] as? Double ?? 0,
        "Total": product["Total"] as? Double ?? 0
    ]

    products.append(item)

}

订单详情

var orderDetails:Parameters = [

            "UserId": OrderDetail["UserId"] as? Int ?? 0,
            //other fields
]

对其他需要的参数做同样的事情,然后你可以用这些预先创建的参数创建你的参数。

let params : [String:Any] = [
        "OrderProducts" : [products] ,//pre created param array
        "OrderDeals" : OrderDeals,
        "OrderDetail" : orderDetails, // pre created param
        "PaymentDetail" : PaymentDetail
    ]

我想你明白了

【讨论】:

  • 感谢您的评论...要试试看..会进一步更新您(y)
  • 对不起我的英语。首先,您需要从 json 响应对象的最底部创建 Parameter 对象。然后你可以将它添加到数组中。这就是理论
  • 我怎样才能映射 OrderDetail 对象..因为它不是一个数组而是一个字典......你能告诉我吗?
  • 更新了答案,请检查。可以直接创建参数对象。然后分配给main
  • 能否添加修改后的代码和控制台输出
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-11
  • 2019-07-28
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多