【问题标题】:How to send a POST request through Swift?如何通过 Swift 发送 POST 请求?
【发布时间】:2017-10-09 23:47:52
【问题描述】:

我有这样的控制器 -

def create
   if (@user = User.find_by_email(params[:email])) && @user.valid_password?(params[:password])
      render json: @user.as_json(only: [:email,:authentication_token]),status: :created
   else 
      render json:('Unauthorized Access')
   end  
end 

当我使用 Postman 提出此请求时,我选择正文,并形成数据并添加电子邮件和密码。这个作品

如何使用 swift 来做同样的事情?这是我尝试过的

let url = URL(string: "http://localhost:3000/api/v1/user_serialized/")

let config = URLSessionConfiguration.default

let request = NSMutableURLRequest(url: url!)

request.httpMethod = "POST"

let bodyData = "email=Test@test.com&password=Test1234"

request.httpBody = bodyData.data(using: String.Encoding.utf8);

let session = URLSession(configuration: config)

let task = session.dataTask(with: url! as URL, completionHandler: {(data, response, error) in
    let json = JSON(data:data!)

    debugPrint(json)
})

task.resume()

【问题讨论】:

  • 对于 Postman 请求,无需询问如何编写 Swift 代码,因为 Postman 会为您编写 Swift 代码。

标签: json swift xcode postman


【解决方案1】:

大家好,我在下面分享一个使用 SWIFT 5+ 在 POST 中发出请求的函数示例。

此函数允许您发送一个 POST 请求,其中包含 API 入口点和 [[String: String]] 形式的参数和一个 Int 以确定输出操作。

对于输出动作,我们使用 Switch Case 调用函数。

操作极其简单。你必须把这两个函数放在你的一个类中。

func MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String {

    var setReturn: String!
    let semaphore = DispatchSemaphore (value: 0)
    var MGGetParam: String! = ""

    for gate in parameters {

        for (key, value) in gate {
            let myParam = key + "=" + value + "&"
            MGGetParam.append(contentsOf: myParam)
        }
    }
            
    let postData =  MGGetParam.data(using: .utf8)

    var request = URLRequest(url: URL(string: endpoint)!,timeoutInterval: 10000)
    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

    request.httpMethod = "POST"
    request.httpBody = postData

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                    print(String(describing: error))
                    semaphore.signal()
                    return
            }
            print(String(data: data, encoding: .utf8)!)
            setReturn = String(data: data, encoding: .utf8)!

        DispatchQueue.main.async {
            self.MGRequestAction(MGGetIdRq: MGSetAction, MGGetData: setReturn)
        }
        semaphore.signal()

    }

    task.resume()
    semaphore.wait()
    return setReturn
}

然后实现这个函数来管理输出

func MGRequestAction(MGGetIdRq: Int, MGGetData: String) {
    
    switch MGGetIdRq {
        case 1:
            // Do something here
        case 2:
            // Do something else here
        case 3:
            // Do something else here again
        default:
            print("Set default action");
    }
    
}

这个怎么用,你有两种可能,第一种是处理什么函数

MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String

返回(字符串)或通过函数传递

MGRequestAction(MGGetIdRq: Int, MGGetData: String)

这将调用你的 Json 解析函数。

MGRequestAction() 函数的参数为​​ Int,用于选择操作和返回请求的字符串

现在要这样使用它:

_ =  MGSetRequestApi(endpoint: MY_END_POINT_API,
                     parameters: [["KEY_1": "VALUE 1"],
                                 ["KEY_2": "VALUE 2"],
                                 ["KEY_3": "VALUE 3"],
                                 ["KEY_4": "VALUE 4"]],
                     MGSetAction: 3)

【讨论】:

    【解决方案2】:

    这里是使用参数“emailaddress”和“password”调用登录 API 的 POST API 示例,其中 userEmailID 和 Userpassword 作为两个字符串分别保存电子邮件和密码的值。

    您可以在视图控制器的任何位置调用此 POST API,如下所示:

    self.postLoginCall(url: "Your post method url") 例子:self.postLoginCall(url: "http://1.0.0.1/api/login.php")

    func postLoginCall(url : String){
    
    
        let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
        request.httpMethod = "POST"
        let postString = "emailaddress=\(userEmailID!)&password=\(Userpassword!)"
        print(postString)
        request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.httpBody = postString.data(using: String.Encoding.utf8)
    
        let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
            guard error == nil && data != nil else {                                                          // check for fundamental networking error
                print("error=\(error)")
                return
            }
    
            do {
            if let responseJSON = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject]{
                print(responseJSON)
                print(responseJSON["status"]!)
    
    
                self.response1 = responseJSON["status"]! as! Int
    
                print(self.response1)
    
                //Check response from the sever
                if self.response1 == 200
                {
                    OperationQueue.main.addOperation {
    
                        //API call Successful and can perform other operatios
                       print("Login Successful")
                    }
    
                }
    
                else
                {
                    OperationQueue.main.addOperation {
    
                        //API call failed and perform other operations
                        print("Login Failed")
    
                    }
    
                }
    
    
            }
            }
            catch {
                print("Error -> \(error)")
            }
    
    
    
        }
    
    
        task.resume()
    
    
    
    }
    

    【讨论】:

      【解决方案3】:

      我创建了一个自定义 HTTP 类,我们可以在其中发送 url、参数,我们将从 API 获取数据。下面是课程。

      import Foundation
      
      //HTTP Methods
      enum HttpMethod : String {
         case  GET
         case  POST
         case  DELETE
         case  PUT
      }
      
      
      class HttpClientApi: NSObject{
      
      //TODO: remove app transport security arbitary constant from info.plist file once we get API's
       var request : URLRequest?
       var session : URLSession?
      
      static func instance() ->  HttpClientApi{
      
          return HttpClientApi()
      }
      
      
      
      func makeAPICall(url: String,params: Dictionary<String, Any>?, method: HttpMethod, success:@escaping ( Data? ,HTTPURLResponse?  , NSError? ) -> Void, failure: @escaping ( Data? ,HTTPURLResponse?  , NSError? )-> Void) {
      
           request = URLRequest(url: URL(string: url)!)
      
          logging.print("URL = \(url)")
      
          if let params = params {
      
      
              let  jsonData = try? JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
      
              request?.setValue("application/json", forHTTPHeaderField: "Content-Type")
              request?.httpBody = jsonData//?.base64EncodedData()
      
      
              //paramString.data(using: String.Encoding.utf8)
          }
          request?.httpMethod = method.rawValue
      
      
          let configuration = URLSessionConfiguration.default
      
          configuration.timeoutIntervalForRequest = 30
          configuration.timeoutIntervalForResource = 30
      
          session = URLSession(configuration: configuration)
          //session?.configuration.timeoutIntervalForResource = 5
          //session?.configuration.timeoutIntervalForRequest = 5
      
          session?.dataTask(with: request! as URLRequest) { (data, response, error) -> Void in
      
              if let data = data {
      
                  if let response = response as? HTTPURLResponse, 200...299 ~= response.statusCode {
                      success(data , response , error as? NSError)
                  } else {
                      failure(data , response as? HTTPURLResponse, error as? NSError)
                  }
              }else {
      
                  failure(data , response as? HTTPURLResponse, error as? NSError)
      
              }
              }.resume()
      
        }
      
      }
      

      现在您可以参考下面的代码来了解如何进行 API 调用。

        var paramsDictionary = [String:Any]()
      
          paramsDictionary["username"] = "BBB"
          paramsDictionary["password"]    = "refef"
      
          HttpClientApi.instance().makeAPICall(url: "Your URL", params:paramsDictionary, method: .POST, success: { (data, response, error) in
      
              // API call is Successfull
      
          }, failure: { (data, response, error) in
      
              // API call Failure
      
          })
      

      【讨论】:

      • 这很简单。谢谢@Balaji Galave
      • 如何在 post 方法中设置 header 并在 body 中传递一些东西?
      【解决方案4】:

      我认为您应该将您的请求而不是 url 传递给 session.dataTask

      这是我的代码的样子:

      private let url = URL(string: "http://example.com/")!
      
      func httpPost(jsonData: Data) {
          if !jsonData.isEmpty {
              var request = URLRequest(url: url)
              request.httpMethod = "POST"
              request.httpBody = jsonData
      
              URLSession.shared.getAllTasks { (openTasks: [URLSessionTask]) in
                  NSLog("open tasks: \(openTasks)")
              }
      
              let task = URLSession.shared.dataTask(with: request, completionHandler: { (responseData: Data?, response: URLResponse?, error: Error?) in
                  NSLog("\(response)")
              })
              task.resume()
          }
      }
      

      【讨论】:

      • 这段代码对我不起作用,但我将请求传递给了 session.dataTask。那行得通。
      • 当我像这样传递参数时,它不会在 http post 请求中传递。为什么?当我在服务器上看到它是POST, /validate-receipt-data, {}.....请帮助我。
      • 请打开一个新问题,提供有关您的问题的更多详细信息。
      猜你喜欢
      • 1970-01-01
      • 2017-04-30
      • 2018-07-18
      • 2011-06-10
      • 1970-01-01
      • 2011-10-24
      • 2010-09-22
      相关资源
      最近更新 更多