How to send a POST request through Swift?

2020-02-20 03:39发布

问题:

I have my controller like this -

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 

When I use Postman to make this request, I choose Body, and form data and adds in the email and password. And this WORKS

How to use swift to do the same? This is what I have tried

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

回答1:

I think you should pass your request instead of the url to session.dataTask

here is how my code looks like:

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


回答2:

I have made a Custom HTTP class where we can sent url, parameter and we will get Data from API. Below is the class.

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

  }

}

Now you can refer below code to get how to make an API call.

  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

    })


回答3:

Here is the Example of POST API for calling Login API with parameters "emailaddress" and "password" with userEmailID and Userpassword as two strings holding values for email and password respectively.

You can call this POST API anywhere in your view controller, as given below:

self.postLoginCall(url: "Your post method url") example: 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()



}