如何在 Alamofire 中请求带有正文和标头的 JSON?

Posted

技术标签:

【中文标题】如何在 Alamofire 中请求带有正文和标头的 JSON?【英文标题】:How to request JSON with body and header in Alamofire? 【发布时间】:2017-07-19 10:23:52 【问题描述】:

我曾尝试使用以下代码进行请求,但结果出现 400 错误。 API 由 header 和 body 组成。标头有两个字段,即“授权”和“内容类型”。正文格式已添加到下面的参数中。

    func file( sender: abc)

        let baseUrl = "url”

        let params: [String : Any] = [
            "profile": [
                “Type": [
                    " Real Estate",
                    "Estater",
                    "Construction",
                    "Entertainment"
                ],
                "Size": [
                    "large",
                    “small”
                ],
                "Level": [
                    “A”,
                    “B”
                ],
                “Name” : [
                    “John”,
                    “Harry”
                ]
            ]
        ]

        let header = [
            "Authorization" : "bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa",
            "Content-Type" : "application/json"
        ]

//        var request = URLRequest(url: URL(string:baseUrl)!)
//        request.httpMethod = HTTPMethod.post.rawValue
//        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
//        request.addValue("bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa", forHTTPHeaderField: "Authorization")
//        let data = try! JSONSerialization.data(withJSONObject: params as Any, options:JSONSerialization.WritingOptions.prettyPrinted)
//        
//        request.httpBody = data

        Alamofire.request("\(baseUrl)", method: .post, parameters: params, headers:header).responseJSON  response in
            print(response.request ?? "no request")  // original URL requ est
            print(response.response ?? "no response") // HTTP URL response
            print(response.data ?? "no data")     // server data
            print(response.result)   // result of response serialization
            print(response.response?.statusCode ?? "noCode")

            if(response.response?.statusCode != nil)
                switch response.response!.statusCode 
                case 200:
                    print("Success")
                    let json = JSON(data: response.data!)
                    print(json)
                    sender.onSuccessCall()
                case 400:
                    print("Error in authentication")
                case 401:
                    print("Error authentication object was not found")
                default:
                    print("dEfault")
                
            
        
    

请帮忙解决这个问题。

【问题讨论】:

我们不知道你的 api 想要你做什么 我只想通过 post 请求获取 JSON 数据,但它显示 400 错误。我的代码有错误吗? 在不知道您的 API 期望什么的情况下,我们无能为力。请在您的问题中包含一个成功的请求,即使它不是来自 swift(即 Postman 请求、curl 请求等)。 如果响应中出现错误,甚至在 seding 数据之前我们也无能为力,信息太少 请尝试使用我的代码,看看它对我来说非常适合我已经用我的 magento api 测试过 【参考方案1】:

我解决了问题,下面添加了正确的方法。

   func file( sender: abc)

    let params: [String : Any] = [
        "profile": [
            “Type": [
                " Real Estate",
                "Estater",
                "Construction",
                "Entertainment"
            ],
            "Size": [
                "large",
                “small”
            ],
            "Level": [
                “A”,
                “B”
            ],
            “Name” : [
                “John”,
                “Harry”
            ]
        ]
    ]

var request = URLRequest(url: URL(string:”url string”)!)
    request.httpMethod = HTTPMethod.post.rawValue
    request.setValue("bearer 5bac059b-eb2b-4e1b-914a-9de5b6a58577", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")

    let data = try! JSONSerialization.data(withJSONObject: params as Any, options:JSONSerialization.WritingOptions.prettyPrinted)

   let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
    print(json!)

    request.httpBody = json!.data(using: String.Encoding.utf8.rawValue)

    Alamofire.request(request).responseJSON  response in
        print(response.request ?? "no request")  // original URL requ est
        print(response.response ?? "no response") // HTTP URL response
        print(response.data ?? "no data")     // server data
        print(response.result)   // result of response serialization
        print(response.response?.statusCode ?? "noCode")

        if(response.response?.statusCode != nil)
            switch response.response!.statusCode 
            case 200:
                print("Success")
                let json = JSON(data: response.data!)
                print(json)
                sender.onSuccessCall()
            case 400:
                print("Error in authentication")
            case 401:
                print("Error authentication object was not found")
            default:
                print("dEfault")
            
        
    

【讨论】:

【参考方案2】:

请试试这个代码

            let urlString = String(format : "Your URL" )


           let params: [String : Any] = [
                "profile": [
                    "Type": [
                    " Real Estate",
                    "Estater",
                    "Construction",
                    "Entertainment"
                    ],
                    "Size": [
                    "large",
                    "small"
                    ],
                    "Level": [
                    "A",
                    "B"
                    ],
                    "Name" : [
                    "John",
                    "Harry"
                    ]
                ]
            ]

            print(params)

            let url = URL(string: urlString)!



  let data = try! JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions.prettyPrinted)

    let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
    if let json = json 
        print(json)
    

    let jsonData = json!.data(using: String.Encoding.utf8.rawValue);



           var request = URLRequest(url: url)
    request.httpMethod = HTTPMethod.post.rawValue
    request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
    request.setValue("bearer e2ff3aa3-63a3-41d1-bc5a3e8c88adeaaa",forHTTPHeaderField: "Authorization")
            request.httpBody = jsonData

            Alamofire.request(request).responseJSON 
                (response) in

                switch response.result 
                case .success(let JSON):
                    print("Success with JSON: \(JSON)")



                    break

                case .failure(let error):
                    print("Request failed with error: \(error)")
                    //callback(response.result.value as? NSMutableDictionary,error as NSError?)
                    break
                


                
                .responseString  response in

                    print("Response String: \(response.result.value)")

            

【讨论】:

【参考方案3】:

有时我们需要 URLEncoding.httpBody 类型作为 post 方法希望它可以帮助你和

 let headers = [
                   // "Content-Type": "application/x-www-form-urlencoded" // try this if its ok then use this otherwise use  "application/json" 
                    // "Content-Type" : "application/json" 
                ]
            let parameters = [

                ]

            Alamofire.request("urlString", method: .post, parameters: parameters, encoding:  URLEncoding.httpBody, headers: headers).responseJSON  (response:DataResponse<Any>) in

                switch(response.result) 
                case.success(let data):
                    print("success",data)
               case.failure(let error):
                    print("Not Success",error)
                    self.view.makeToast(message: "Server Error!!")
                

            

【讨论】:

你把“Authorization”:“bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa”放在带有内容类型的标题中并尝试了这个 是的,我试过了,但是不行。我也试过这个代码 request.setValue("application/json", forHTTPHeaderField: "Content-Type" request.addValue("bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa", forHTTPHeaderField: "Authorization" 去 alamofire github 并尝试从他们更改 urlEncoding 类型,它们是关于 urlEncoding 的参考,有时我们的 urlEncoding 似乎不适用于 post 方法类型 让 params :Parameters = [ ] 在参数中尝试一次:[String : Any] 我认为它的问题在标头请求中。【参考方案4】:

使用URLConvertible在baseUrl中输入url

解决方法如下:

func file( sender: abc)

        let baseU = URL(string:"url")
        let baseUrl = baseU as! URLConvertible

        let params: [String : Any] = [
            "profile": [
                "Type": [
                " Real Estate",
                "Estater",
                "Construction",
                "Entertainment"
                ],
                "Size": [
                "large",
                "small"
                ],
                "Level": [
                "A",
                "B"
                ],
                "Name" : [
                "John",
                "Harry"
                ]
            ]
        ]

        let header = [
            "Authorization" : "bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa",
            "Content-Type" : "application/json"
        ]

        //        var request = URLRequest(url: URL(string:baseUrl)!)
        //        request.httpMethod = HTTPMethod.post.rawValue
        //        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        //        request.addValue("bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa", forHTTPHeaderField: "Authorization")
        //        let data = try! JSONSerialization.data(withJSONObject: params as Any, options:JSONSerialization.WritingOptions.prettyPrinted)
        //
        //        request.httpBody = data

        Alamofire.request(baseUrl, method: .post, parameters: params, headers:header).responseJSON  response in
            print(response.request ?? "no request")  // original URL requ est
            print(response.response ?? "no response") // HTTP URL response
            print(response.data ?? "no data")     // server data
            print(response.result)   // result of response serialization
            print(response.response?.statusCode ?? "noCode")

            if(response.response?.statusCode != nil)
                switch response.response!.statusCode 
                case 200:
                    print("Success")
                    let json = JSON(data: response.data!)
                    print(json)
                    sender.onSuccessCall()
                case 400:
                    print("Error in authentication")
                case 401:
                    print("Error authentication object was not found")
                default:
                    print("dEfault")
                
            
        

【讨论】:

谢谢,@Sakir Sherasiya。我试过了,但没用。 API 调用后。 我知道。我的意思是如果传递错误的 json 那么你就对了? 让我们continue this discussion in chat.

以上是关于如何在 Alamofire 中请求带有正文和标头的 JSON?的主要内容,如果未能解决你的问题,请参考以下文章