【问题标题】:How to send a POST request with BODY in swift如何在 swift 中使用 BODY 发送 POST 请求
【发布时间】:2015-11-06 02:00:24
【问题描述】:

我正在尝试使用 Alamofire 快速发出带有正文的发布请求。

我的 json 身体看起来像:

{
    "IdQuiz" : 102,
    "IdUser" : "iosclient",
    "User" : "iosclient",
    "List":[
        {
        "IdQuestion" : 5,
        "IdProposition": 2,
        "Time" : 32
        },
        {
        "IdQuestion" : 4,
        "IdProposition": 3,
        "Time" : 9
        }
    ]
}

我正在尝试使用 NSDictionnary 制作 let list,它看起来像:

[[Time: 30, IdQuestion: 6510, idProposition: 10], [Time: 30, IdQuestion: 8284, idProposition: 10]]

我使用 Alamofire 的请求看起来像:

Alamofire.request(.POST, "http://myserver.com", parameters: ["IdQuiz":"102","IdUser":"iOSclient","User":"iOSClient","List":list ], encoding: .JSON)
            .response { request, response, data, error in
            let dataString = NSString(data: data!, encoding:NSUTF8StringEncoding)
                println(dataString)
        }

请求有错误,我认为问题出在字典列表上,因为如果我在没有列表的情况下发出请求,它可以正常工作,所以有什么想法吗?


我已经尝试了建议的解决方案,但我遇到了同样的问题:

 let json = ["List":list,"IdQuiz":"102","IdUser":"iOSclient","UserInformation":"iOSClient"]
        let data = NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted,error:nil)
        let jsons = NSString(data: data!, encoding: NSUTF8StringEncoding)



    Alamofire.request(.POST, "http://myserver.com", parameters: [:], encoding: .Custom({
        (convertible, params) in
        var mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
        mutableRequest.HTTPBody = jsons!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
        return (mutableRequest, nil)
    }))
        .response { request, response, data, error in
        let dataString = NSString(data: data!, encoding:NSUTF8StringEncoding)
           println(dataString)
    }

【问题讨论】:

  • 感谢您的评论,但您提供的帖子没有帮助,我也不想将字符串作为正文传递,所以请您仔细阅读帖子
  • @YasserB。将您的 JSON 转换为 NSString(有相应的方法),然后使用 @Bhavin 的链接?
  • @Larme 如果你提供一个例子会很有帮助
  • @Larme 我已经尝试了建议的解决方案,但我遇到了同样的问题,除非我从儿子正文中删除列表,否则请求不起作用

标签: json swift put alamofire


【解决方案1】:

Alamofire ~5.2Swift 5

你可以构建你的参数数据

使用fake json api

struct Parameter: Encodable {
     let token: String = "xxxxxxxxxx"
     let data: Dictionary = [
        "id": "personNickname",
        "email": "internetEmail",
        "gender": "personGender",
     ]
}

 let parameters = Parameter()

 AF.request("https://app.fakejson.com/q", method: .post, parameters: parameters).responseJSON { response in
            print(response)
        }

【讨论】:

    【解决方案2】:

    如果您使用的是swift4Alamofire v4.0,那么接受的代码将如下所示:

                let parameters: Parameters = [ "username" : email.text!, "password" : password.text! ]
                let urlString = "https://api.harridev.com/api/v1/login"
                let url = URL.init(string: urlString)
                Alamofire.request(url!, method: .put, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
                     switch response.result
                    {
                    case .success(let json):
                        let jsonData = json as! Any
                        print(jsonData)
                    case .failure(let error):
                        self.errorFailer(error: error)
                    }
                }
    

    【讨论】:

      【解决方案3】:

      接受的答案 Xcode 11 - Swift 5 - Alamofire 5.0

      func postRequest() {
          let parameters: [String: Any] = [
              "IdQuiz" : 102,
              "IdUser" : "iosclient",
              "User" : "iosclient",
              "List": [
                  [
                      "IdQuestion" : 5,
                      "IdProposition": 2,
                      "Time" : 32
                  ],
                  [
                      "IdQuestion" : 4,
                      "IdProposition": 3,
                      "Time" : 9
                  ]
              ]
          ]
          AF.request("http://myserver.com", method:.post, parameters: parameters,encoding: JSONEncoding.default) .responseJSON { (response) in
              print(response)
          }
      }
      

      【讨论】:

      • 重要!使用编码:JSONEncoding.default。我已经敲了好几个小时了……默认是 GET 参数的编码。
      • 参数类型“JSONEncoding”不符合预期类型“ParameterEncoder”
      • @Takasur 使用 JSONEncoding.default
      • 我放弃了生活。然后你救了我。谢谢
      【解决方案4】:

      Alamofire 使用 POST、参数和标头获取数据

      func feedbackApi(){
          DispatchQueue.main.async {
              let headers = [
                  "Content-Type": "application/x-www-form-urlencoded",
                  "Authorization": "------"
              ]
              let url = URL(string: "---------")
              var parameters = [String:AnyObject]()
              parameters =  [
                  "device_id":"-----" as AnyObject,
                  "user_id":"----" as AnyObject,
                  "cinema_id":"-----" as AnyObject,
                  "session_id":"-----" as AnyObject,
              ]
             Alamofire.request(url!, method: .post, parameters: parameters,headers:headers).responseJSON { response in
                      switch response.result{
                      case.success(let data):
                          self.myResponse = JSON(data)
                          print(self.myResponse as Any)
                          let slide = self.myResponse!["sliders"]
                          print(slide)
                          print(slide.count)
                          for i in 0..<slide.count{
                              let single = Sliders(sliderJson: slide[i])
                              self.slidersArray.append(single)
                          }
                          DispatchQueue.main.async {
                              self.getSliderCollection.reloadData()
                          }
                      case .failure(let error):
                          print("dddd",error)
                      }
      
              }
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        如果有人想知道如何处理模型和东西,请参阅下文

                var itemArr: [Dictionary<String, String>] = []
                for model in models {
                      let object = ["param1": model.param1,
                                    "param2": model.param2]
                      itemArr.append(object as! [String : String])
                }
        
                let param = ["field1": someValue,
                             "field2": someValue,
                             "field3": itemArr] as [String : Any]
        
                let url: URLConvertible = "http://------"
        
                Alamofire.request(url, method: .post, parameters: param, encoding: JSONEncoding.default)
                    .responseJSON { response in
                        self.isLoading = false
                        switch response.result {
                        case .success:
                            break
                        case .failure:
                            break
                        }
                }
        

        【讨论】:

          【解决方案6】:
          func get_Contact_list()
          {
              ApiUtillity.sharedInstance.showSVProgressHUD(text: "Loading..")
              let cont_nunber = contact_array as NSArray
              print(cont_nunber)
          
              let token = UserDefaults.standard.string(forKey: "vAuthToken")!
              let apiToken = "Bearer \(token)"
          
          
              let headers = [
                  "Vauthtoken": apiToken,
                  "content-type": "application/json"
              ]
          
              let myArray: [Any] = cont_nunber as! [Any]
              let jsonData: Data? = try? JSONSerialization.data(withJSONObject: myArray, options: .prettyPrinted)
              //        var jsonString: String = nil
              var jsonString = String()
              if let aData = jsonData {
                  jsonString = String(data: aData, encoding: .utf8)!
              }
          
              let url1 = "URL"
              var request = URLRequest(url: URL(string: url1)!)
              request.httpMethod = "POST"
              request.allHTTPHeaderFields = headers
              request.httpBody = jsonData as! Data
          
              //        let session = URLSession.shared
          
              let task = URLSession.shared.dataTask(with: request) { data, response, error in
                  guard let data = data, error == nil else {
                      print("error=\(String(describing: error))")
                      ApiUtillity.sharedInstance.dismissSVProgressHUD()
                      return
                  }
          
                  print("response = \(String(describing: response))")
          
          
                  let responseString = String(data: data, encoding: .utf8)
                  print("responseString = \(String(describing: responseString))")
          
                  let json =  self.convertStringToDictionary(text: responseString!)! as NSDictionary
                  print(json)
          
                  let status = json.value(forKey: "status") as! Int
          
                  if status == 200
                  {
          
                      let array = (json.value(forKey: "data") as! NSArray).mutableCopy() as! NSMutableArray
          
          
                  }
                  else if status == 401
                  {
                      ApiUtillity.sharedInstance.dismissSVProgressHUD()
          
                  }
                  else
                  {
                      ApiUtillity.sharedInstance.dismissSVProgressHUD()
                  }
          
          
              }
              task.resume()
          }
          
          func convertStringToDictionary(text: String) -> [String:AnyObject]? {
              if let data = text.data(using: String.Encoding.utf8) {
                  do {
                      let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
                      return json
                  } catch {
                      print("Something went wrong")
                  }
              }
              return nil
          }
          

          【讨论】:

            【解决方案7】:

            如果您使用的是 Alamofire v4.0+,那么接受的答案将如下所示:

            let parameters: [String: Any] = [
                "IdQuiz" : 102,
                "IdUser" : "iosclient",
                "User" : "iosclient",
                "List": [
                    [
                        "IdQuestion" : 5,
                        "IdProposition": 2,
                        "Time" : 32
                    ],
                    [
                        "IdQuestion" : 4,
                        "IdProposition": 3,
                        "Time" : 9
                    ]
                ]
            ]
            
            Alamofire.request("http://myserver.com", method: .post, parameters: parameters, encoding: JSONEncoding.default)
                .responseJSON { response in
                    print(response)
                }
            

            【讨论】:

            • 太棒了!请更改已接受的答案! :) 或结合当前的 Alamofire 3 和 4 解决方案。
            • 同意 - 这是 JSONEncoding 的明确声明,以消除为我所做的类型。
            • @Gianni Carlo 我使用的和你的答案一样,但是在我的成功回复中我收到了错误。
            • @Ramakrishna 可能与您使用的 API 有关。为了解析响应,我通常使用 SwiftyJSON 库,让我知道你收到什么样的错误
            • 感谢您的回复。我得到了解决方案。
            【解决方案8】:

            以下是我如何使用 swift 创建 Http POST 请求,该请求需要带有 Json 编码和标头的参数。

            创建的 API 客户端 BKCAPIClient 作为一个共享实例,它将包括所有类型的请求,如 POST、GET、PUT、DELETE 等。

            func postRequest(url:String, params:Parameters?, headers:HTTPHeaders?, completion:@escaping (_ responseData:Result<Any>?, _ error:Error?)->Void){
                Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON {
                    response in
                    guard response.result.isSuccess,
                        (response.result.value != nil) else {
                            debugPrint("Error while fetching data: \(String(describing: response.result.error))")
                            completion(nil,response.result.error)
                            return
                    }
                    completion(response.result,nil)
                }
            }
            

            创建的操作类包含特定请求所需的所有数据,还包含完成块内的解析逻辑。

            func requestAccountOperation(completion: @escaping ( (_ result:Any?, _ error:Error?) -> Void)){
                BKCApiClient.shared.postRequest(url: BKCConstants().bkcUrl, params: self.parametrs(), headers: self.headers()) { (result, error) in
                    if(error != nil){
                        //Parse and save to DB/Singletons.
                    }
                    completion(result, error)
                }
            }
            func parametrs()->Parameters{
                return ["userid”:”xnmtyrdx”,”bcode":"HDF"] as Parameters
            }
            func headers()->HTTPHeaders{
                return ["Authorization": "Basic bXl1c2VyOm15cGFzcw",
                        "Content-Type": "application/json"] as HTTPHeaders
            }
            

            在我们需要这些数据的任何视图控制器中调用 API

            func callToAPIOperation(){
            let accOperation: AccountRequestOperation = AccountRequestOperation()
            accOperation.requestAccountOperation{(result, error) in
            
            }}
            

            【讨论】:

              【解决方案9】:

              我稍微编辑了SwiftDeveloper 的答案,因为它不适合我。我还添加了 Alamofire 验证。

              let body: NSMutableDictionary? = [
                  "name": "\(nameLabel.text!)",
                  "phone": "\(phoneLabel.text!))"]
              
              let url = NSURL(string: "http://server.com" as String)
              var request = URLRequest(url: url! as URL)
              request.httpMethod = "POST"
              request.setValue("application/json", forHTTPHeaderField: "Content-Type")
              let data = try! JSONSerialization.data(withJSONObject: body!, options: JSONSerialization.WritingOptions.prettyPrinted)
              
              let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
              if let json = json {
                  print(json)
              }
              request.httpBody = json!.data(using: String.Encoding.utf8.rawValue)
              let alamoRequest = Alamofire.request(request as URLRequestConvertible)
              alamoRequest.validate(statusCode: 200..<300)
              alamoRequest.responseString { response in
              
                  switch response.result {
                      case .success:
                          ...
                      case .failure(let error):
                          ...
                  }
              }
              

              【讨论】:

              • 在 Alamofire 4.9.1 和 Swift 5.1 中仍然有效。非常感谢
              【解决方案10】:

              到目前为止,我不喜欢任何其他答案(可能除了 SwiftDeveloper 的one),因为它们要么要求您反序列化您的 JSON,只是为了再次序列化它,要么关心JSON 本身。

              正确的answer 已由 afrodev 在另一个问题中发布。你应该去投票。

              以下只是我的改编,有一些小的改动(主要是明确的 UTF-8 字符集)。

              let urlString = "https://example.org/some/api"
              let json = "{\"What\":\"Ever\"}"
              
              let url = URL(string: urlString)!
              let jsonData = json.data(using: .utf8, allowLossyConversion: false)!
              
              var request = URLRequest(url: url)
              request.httpMethod = HTTPMethod.post.rawValue
              request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
              request.httpBody = jsonData
              
              Alamofire.request(request).responseJSON {
                  (response) in
              
                  print(response)
              }
              

              【讨论】:

              • 我同意@SwiftDeveloper 的答案比您提到的“正确”答案更好并且(在我看来)更完整。但我要争论两点。一,您提到的“正确答案”存在toJSONString不是本机方法的缺陷,因此它基本上是一个您必须实现的黑匣子。二,你给出的答案,提供了一个 var json,它以 json 字符串开头,实际上没有人有这样的参数,除非你以这种方式在本地转换和存储它们。
              • @GianniCarlo 1)在我的回答中没有toJSONString,2)“实际上没有人有这样的参数”——这是做了很多假设; JSON 可能来自应用程序的不同部分,与发出请求完全无关,网络代码对此一无所知。
              • 感谢您让我的生活更轻松!!!1 我正在使用带有 Flask 后端的 Alamofire。从邮递员那里一切正常。但是从 Alamofire 那里它不起作用。 HTTP 正文和 URL 参数以及如何设置它们。再次感谢。
              【解决方案11】:

              Xcode 8.X 、Swift 3.X

              易于使用;

                  let params:NSMutableDictionary? = [
                  "IdQuiz" : 102,
                  "IdUser" : "iosclient",
                  "User" : "iosclient",
                  "List": [
                      [
                          "IdQuestion" : 5,
                          "IdProposition": 2,
                          "Time" : 32
                      ],
                      [
                          "IdQuestion" : 4,
                          "IdProposition": 3,
                          "Time" : 9
                      ]
                  ]
              ];
                          let ulr =  NSURL(string:"http://myserver.com" as String)
                          let request = NSMutableURLRequest(url: ulr! as URL)
                          request.httpMethod = "POST"
                          request.setValue("application/json", forHTTPHeaderField: "Content-Type")
                          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)
                          }
                          request.httpBody = json!.data(using: String.Encoding.utf8.rawValue);
              
              
                          Alamofire.request(request as! URLRequestConvertible)
                              .responseJSON { response in
                                  // do whatever you want here
                                 print(response.request)  
                                 print(response.response) 
                                 print(response.data) 
                                 print(response.result)
              
                          }
              

              【讨论】:

                【解决方案12】:

                我想通知的更改很少。从现在开始,您可以从响应对象访问请求、JSON、错误。

                        let urlstring = "Add URL String here"
                        let parameters: [String: AnyObject] = [
                            "IdQuiz" : 102,
                            "IdUser" : "iosclient",
                            "User" : "iosclient",
                            "List": [
                                [
                                    "IdQuestion" : 5,
                                    "IdProposition": 2,
                                    "Time" : 32
                                ],
                                [
                                    "IdQuestion" : 4,
                                    "IdProposition": 3,
                                    "Time" : 9
                                ]
                            ]
                        ]
                
                        Alamofire.request(.POST, urlstring, parameters: parameters, encoding: .JSON).responseJSON { response in
                            print(response.request)  // original URL request
                            print(response.response) // URL response
                            print(response.data)     // server data
                            print(response.result)   // result of response serialization
                
                            if let JSON = response.result.value {
                                print("JSON: \(JSON)")
                            }
                            response.result.error
                        }
                

                【讨论】:

                  【解决方案13】:

                  你已经接近了。参数字典格式看起来不正确。您应该尝试以下方法:

                  let parameters: [String: AnyObject] = [
                      "IdQuiz" : 102,
                      "IdUser" : "iosclient",
                      "User" : "iosclient",
                      "List": [
                          [
                              "IdQuestion" : 5,
                              "IdProposition": 2,
                              "Time" : 32
                          ],
                          [
                              "IdQuestion" : 4,
                              "IdProposition": 3,
                              "Time" : 9
                          ]
                      ]
                  ]
                  
                  Alamofire.request(.POST, "http://myserver.com", parameters: parameters, encoding: .JSON)
                      .responseJSON { request, response, JSON, error in
                          print(response)
                          print(JSON)
                          print(error)
                      }
                  

                  希望这能解决您的问题。如果没有,请回复,我会相应地调整我的答案。

                  【讨论】:

                  • 由于无法将nil 分配给AnyObject,如何将JSON 的某些属性设置为null?
                  • @JaseemAbbas 检查您的 Alamofire 版本,如果您使用的是 v4.0+,请在下面查看我的答案
                  • 在编码为.urlEncoding的情况下如何发送此类参数
                  • 无法将“Int”类型的值转换为预期的字典值类型“AnyObject”
                  • 如果“List”参数的值有1000个列表元素怎么办?
                  猜你喜欢
                  • 1970-01-01
                  • 2017-10-09
                  • 1970-01-01
                  • 2016-11-16
                  • 2019-03-03
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多