JSON не может быть сериализовано из-за ошибки: данные не могут быть прочитаны, потому что они не в правильном формате. [Swift 4.2] - PullRequest
0 голосов
/ 27 марта 2020

как можно отправить запрос POST с вложенным объектом, таким как массив словаря, в качестве параметра в теле HTTP с Alamofire 5? Мне не удалось преобразовать объект в правильный формат с помощью JSONSerialization. Не знаете, что делать дальше?

My 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)
                        }
                }
        }
}

Ошибка, которую я получаю

enter image description here

Мой плохо отформатированный Json объект выглядит следующим образом (печатается после преобразования)

enter image description here

Отредактировано:

Веселье c выглядит так после Решения Дилана (но все же выдает ту же ошибку)

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)
                        }
                }
        }
}

1 Ответ

1 голос
/ 27 марта 2020

В alamofire мы не можем напрямую преобразовать этот вид json (с вложенными массивами). Вам следует преобразовать его объекты в параметры из внутреннего во внешний.

Прежде чем добавить OrderProduct в params , вам нужно l oop массив 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
    ]

Я думаю, вы получили это

...