簡體   English   中英

由於錯誤,JSON 無法序列化:無法讀取數據,因為它的格式不正確。[Swift 4.2]

[英]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]

如何使用 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)
                        }
                }
        }
}

在 alamofire 中,我們無法直接轉換這些類型的 json(帶有嵌套數組)。您應該將其對象從內部轉換為外部參數。

在將OrderProduct添加到params之前,您需要循環 OrderProduct 數組並創建 Alamofire Parameter 對象數組,然后您可以將該數組添加到您的 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
    ]

我想你明白了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM