如何使用alamofire快速发布带有json顺序的请求?

时间:2020-01-24 09:13:14

标签: ios json swift xcode alamofire

我需要为我的应用程序提供一种付款方式,并且我必须发布一个带有JSON数据的请求才能与API进行通信。一切对我来说似乎都是正确的。我在代码中找不到任何错误,但我假设JSON不按顺序发布。这重要吗?因为响应表示失败,但我找不到其他东西。如果JSON顺序很重要,我该怎么做?我是新手,请帮助我。 这是我的代码:

 func mainRequestForPayment() {

      )

        let headers: HTTPHeaders = [
            "accept": "application/json",
            "content-type": "application/json",
            "authorization": "\(self.authValue)",
            "x-iyzi-rnd": "\(self.randomString)",
            "cache-control": "no-cache"
        ]


        let url = "MY_URL"

        let parameters: [String: Any] = [
        "locale": "tr",
        "conversationId": "123456789",
        "price": "1.1",
        "paidPrice": "1.1",
        "installment": 1,
        "paymentChannel": "WEB",
        "basketId": "B67832",
        "paymentGroup": "PRODUCT",
        "paymentCard": [
            "cardHolderName": "CARD_HOLDER_NAME",
            "cardNumber": "CARD_NUMBER",
            "expireYear": "CARD_YEAR",
            "expireMonth": "01",
            "cvc": "123",
            "registerCard": 0
        ],
        "buyer": [
            "id": "BY789",
            "name": "John",
            "surname": "Doe",
            "identityNumber": "74300864791",
            "email": "email@email.com",
            "gsmNumber": "+905350000000",
            "registrationAddress": "Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1",
            "city": "Istanbul",
            "country": "Turkey",
            "zipCode": "34732",
            "ip": "85.34.78.112"
        ],
        "shippingAddress": [
            "address": "Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1",
            "zipCode": "34742",
            "contactName": "Jane Doe",
            "city": "Istanbul",
            "country": "Turkey"
        ],
        "billingAddress": [
            "address": "Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1",
            "zipCode": "34742",
            "contactName": "Jane Doe",
            "city": "Istanbul",
            "country": "Turkey"
        ],
        "basketItems": [
            [
                "id": "BI101",
                "price": "0.3",
                "name": "Binocular",
                "category1": "Collectibles",
                "category2": "Accessories",
                "itemType": "PHYSICAL"
            ],
            [
                "id": "BI102",
                "price": "0.5",
                "name": "Game code",
                "category1": "Game",
                "category2": "Online Game Items",
                "itemType": "VIRTUAL"
            ],
            [
                "id": "BI103",
                "price": "0.2",
                "name": "Usb",
                "category1": "Electronics",
                "category2": "Usb / Cable",
                "itemType": "PHYSICAL"
            ]
        ],
        "currency": "TRY"
            ]


        Alamofire.request(url, method: .post, parameters: parameters , encoding: JSONEncoding.default, headers: headers)
            .responseJSON { (response) in
                print(parameters)
                switch response.result {
                case .success(let value):
                    let swiftyJson = JSON(value)
                    print ("return as JSON using swiftyJson is: \(swiftyJson)")
                case .failure(let error):
                    print ("error: \(error)")
                }

        }


    }

我看不到我的错在哪里?再有什么办法可以在发布请求中下订单?谢谢大家。

我得到了答复:

return as JSON using swiftyJson is: {
  "conversationId" : "123456789",
  "locale" : "tr",
  "errorCode" : "1000",
  "status" : "failure",
  "systemTime" : 1579858355103,
  "errorMessage" : "Invalid signature"
}

2 个答案:

答案 0 :(得分:0)

JSON顺序通常并不重要,因为JSON规范并未将其定义为JSON对象的要求,但某些设计欠佳的后端确实要求它。您确实需要检查与之通信的后端的要求。

此外,Swift的Dictionary类型是任意排序的,并且该顺序可能在您的应用运行之间以及用于编译代码的Swift版本之间改变。

最后,Swift的JSONEncoder和Apple的JSONSerialization类型都无法提供要求严格订购的方法。 JSONSerialization最多提供.sortedKeys选项,这将为您提供有保证的(字母顺序)顺序,但可能不是您在其中声明参数的顺序。使用备用Encoder,如果您有Codable类型(我建议您使用SwiftyJSON而不是SwiftyJSON类型),可能会更好地保证顺序,但是您只需要真正关心后端的需求即可。

顺便说一句,我建议您将静态HTTPHeader属性用作您的HTTPHeaders值,而不是使用原始字符串,这样会更加方便。例如:

let headers: HTTPHeaders = [.accept("application/json"),
                            .contentType("application/json")]

答案 1 :(得分:-1)

使用此类

///////////////////////////////////////////// < / p>

导入基金会

导入UIKit

导入Alamofire

Class ServicesClass_New:NSObject {

var delegate : ServicesClassDelegate!

typealias CompletionBlock = (_ result : Dictionary<String, Any>?, _ error : Error?) -> Void
typealias CompletionDataBlock = (_ result : Data?) -> Void
typealias ProgressBlock = (_ progressData : Progress) -> Void

//MARK: Shared Instance

static let sharedInstance : ServicesClass = {
    let instance = ServicesClass()
    return instance
}()

static func getDataFromURlWith(url:String,parameters:Dictionary<String, Any>?, requestName:String,completionBlock : @escaping CompletionBlock)
{

    print("net available")
    Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in

        switch(response.result) {
        case .success(_):
            if let data = response.result.value
            {
                //print(response.result.value!)
                //print(data)

                var dic : Dictionary<String,Any> = Dictionary()

                if data as? Array<Dictionary<String,Any>> != nil
                {
                    dic["data"] = data as? Array<Dictionary<String,Any>>
                    completionBlock(dic,nil)
                }
                else
                {
                    completionBlock(data as? Dictionary<String,Any>,nil)
                }
            }

            break

        case .failure(_):
            print(response.result.error!)
            completionBlock(nil ,response.result.error!)
            break

        }
    }

}

static func postDataFromURL(url:String,parameters:Dictionary<String, Any>?, requestName:String,completionBlock : @escaping CompletionBlock)
{
    print("net available")
    //application/json 
    //multipart/form-data
    let hders : HTTPHeaders = [ "Content-Type" : "application/json"] as [String : String]

    Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: hders).responseJSON { response in

        switch(response.result) {
        case .success(_):
            if let dict = response.result.value
            {
                let data = dict as! Dictionary<String,Any>

                // print(response.result.value!)
                // print(data)
                completionBlock(data as Dictionary,nil)
            }

            break

        case .failure(let error):
            print((error as NSError).localizedDescription)
            completionBlock(nil ,response.result.error!)
            print("\(error.localizedDescription)")

            break

        }
    }
}

static func downloadFile(strUrl : String, progressBlock : @escaping ProgressBlock, completionBlock : @escaping CompletionDataBlock)
{
    let utilityQueue = DispatchQueue.global(qos: .utility)

    Alamofire.request(URL.init(string: strUrl)!).downloadProgress(queue: utilityQueue, closure: { (progress) in

        progressBlock(progress)
    })
        .responseData { (response) in

            if let data = response.result.value
            {
                completionBlock(data)
            }
            else
            {
                completionBlock(nil)
            }
    }

}

static func uploadData(url:String,parameters:Dictionary<String, Any>,requestName:String,arrImg:[UIImage],arrVideos:[URL],completionBlock : @escaping CompletionBlock)
{

    print("net available")

    let hders = [

        "Content-Type": "application/json"
    ]

    Alamofire.upload(multipartFormData:
        {
            MultipartFormData in

            for img in arrImg
            {
                let imageData = UIImageJPEGRepresentation(img , 0.8)!
                MultipartFormData.append(imageData, withName: "image" , fileName:"file\(index).jpg", mimeType:"image/jpeg")
            }

            index = 0
            for video in arrVideos
            {
                index = index + 1
                var videoData : Data = Data()
                do
                {
                    videoData = try Data.init(contentsOf: URL.init(fileURLWithPath: video.path))
                    MultipartFormData.append(videoData, withName: "video", fileName:"file\(index).mp4",mimeType: "video/mp4")
                }
                catch
                {

                }
            }
            for (key, value) in parameters
            {
                MultipartFormData.append((value as! String).data(using: String.Encoding.utf8)!, withName: key)
            }

    }, to:url,method:.post,headers:hders, encodingCompletion: {
        encodingResult in

        //["content-type" : "application/json"]
        switch encodingResult
        {
        case .success(let upload, _, _):
            print("image uploaded")
            upload.responseJSON { response in

                if let JSON = response.result.value
                {
                    print("JSON: \(JSON)")
                }

                if let dict = response.result.value
                {
                    let data = dict as! Dictionary<String,Any>

                    print(response.result.value!)
                    print(data)

                    completionBlock(data as Dictionary,nil)

                }
            }

            break

        case .failure(let encodingError):
            completionBlock(nil ,encodingError)
            break
        }
    } )

}

}

///在您要调用API的地方调用协议。 //有多种方法,例如:GET,POST ....