HTTP Request in Swift with POST method

前端 未结 7 905
名媛妹妹
名媛妹妹 2020-11-22 05:46

I\'m trying to run a HTTP Request in Swift, to POST 2 parameters to a URL.

Example:

Link: www.thisismylink.com/postName.php

Params:

相关标签:
7条回答
  • 2020-11-22 06:13
    let session = URLSession.shared
            let url = "http://...."
            let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
            request.httpMethod = "POST"
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            var params :[String: Any]?
            params = ["Some_ID" : "111", "REQUEST" : "SOME_API_NAME"]
            do{
                request.httpBody = try JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions())
                let task = session.dataTask(with: request as URLRequest as URLRequest, completionHandler: {(data, response, error) in
                    if let response = response {
                        let nsHTTPResponse = response as! HTTPURLResponse
                        let statusCode = nsHTTPResponse.statusCode
                        print ("status code = \(statusCode)")
                    }
                    if let error = error {
                        print ("\(error)")
                    }
                    if let data = data {
                        do{
                            let jsonResponse = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions())
                            print ("data = \(jsonResponse)")
                        }catch _ {
                            print ("OOps not good JSON formatted response")
                        }
                    }
                })
                task.resume()
            }catch _ {
                print ("Oops something happened buddy")
            }
    
    0 讨论(0)
  • 2020-11-22 06:18

    Swift 4 and above

    @IBAction func submitAction(sender: UIButton) {
    
        //declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
    
        let parameters = ["id": 13, "name": "jack"]
    
        //create the url with URL
        let url = URL(string: "www.thisismylink.com/postName.php")! //change the url
    
        //create the session object
        let session = URLSession.shared
    
        //now create the URLRequest object using the url object
        var request = URLRequest(url: url)
        request.httpMethod = "POST" //set http method as POST
    
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body
        } catch let error {
            print(error.localizedDescription)
        }
    
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
    
        //create dataTask using the session object to send data to the server
        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
    
            guard error == nil else {
                return
            }
    
            guard let data = data else {
                return
            }
    
            do {
                //create json object from data
                if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                    print(json)
                    // handle json...
                }
            } catch let error {
                print(error.localizedDescription)
            }
        })
        task.resume()
    }
    
    0 讨论(0)
  • 2020-11-22 06:19

    All the answers here use JSON objects. This gave us problems with the $this->input->post() methods of our Codeigniter controllers. The CI_Controller cannot read JSON directly. We used this method to do it WITHOUT JSON

    func postRequest() {
        // Create url object
        guard let url = URL(string: yourURL) else {return}
    
        // Create the session object
        let session = URLSession.shared
    
        // Create the URLRequest object using the url object
        var request = URLRequest(url: url)
    
        // Set the request method. Important Do not set any other headers, like Content-Type
        request.httpMethod = "POST" //set http method as POST
    
        // Set parameters here. Replace with your own.
        let postData = "param1_id=param1_value&param2_id=param2_value".data(using: .utf8)
        request.httpBody = postData
    
        // Create a task using the session object, to run and return completion handler
        let webTask = session.dataTask(with: request, completionHandler: {data, response, error in
        guard error == nil else {
            print(error?.localizedDescription ?? "Response Error")
            return
        }
        guard let serverData = data else {
            print("server data error")
            return
        }
        do {
            if let requestJson = try JSONSerialization.jsonObject(with: serverData, options: .mutableContainers) as? [String: Any]{
                print("Response: \(requestJson)")
            }
        } catch let responseError {
            print("Serialisation in error in creating response body: \(responseError.localizedDescription)")
            let message = String(bytes: serverData, encoding: .ascii)
            print(message as Any)
        }
    
        // Run the task
        webTask.resume()
    }
    

    Now your CI_Controller will be able to get param1 and param2 using $this->input->post('param1') and $this->input->post('param2')

    0 讨论(0)
  • 2020-11-22 06:22

    Heres the method I used in my logging library: https://github.com/goktugyil/QorumLogs

    This method fills html forms inside Google Forms.

        var url = NSURL(string: urlstring)
    
        var request = NSMutableURLRequest(URL: url!)
        request.HTTPMethod = "POST"
        request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
        var connection = NSURLConnection(request: request, delegate: nil, startImmediately: true)
    
    0 讨论(0)
  • 2020-11-22 06:22
    @IBAction func btn_LogIn(sender: AnyObject) {
    
        let request = NSMutableURLRequest(URL: NSURL(string: "http://demo.hackerkernel.com/ios_api/login.php")!)
        request.HTTPMethod = "POST"
        let postString = "email: test@test.com & password: testtest"
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request){data, response, error in
            guard error == nil && data != nil else{
                print("error")
                return
            }
            if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200{
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(response)")
            }
            let responseString = String(data: data!, encoding: NSUTF8StringEncoding)
            print("responseString = \(responseString)")
        }
        task.resume()
    }
    
    0 讨论(0)
  • 2020-11-22 06:25

    In Swift 3 and later you can:

    let url = URL(string: "http://www.thisismylink.com/postName.php")!
    var request = URLRequest(url: url)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    let parameters: [String: Any] = [
        "id": 13,
        "name": "Jack & Jill"
    ]
    request.httpBody = parameters.percentEncoded()
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, 
            let response = response as? HTTPURLResponse, 
            error == nil else {                                              // check for fundamental networking error
            print("error", error ?? "Unknown error")
            return
        }
    
        guard (200 ... 299) ~= response.statusCode else {                    // check for http errors
            print("statusCode should be 2xx, but is \(response.statusCode)")
            print("response = \(response)")
            return
        }
    
        let responseString = String(data: data, encoding: .utf8)
        print("responseString = \(responseString)")
    }
    
    task.resume()
    

    Where:

    extension Dictionary {
        func percentEncoded() -> Data? {
            return map { key, value in
                let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
                let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
                return escapedKey + "=" + escapedValue
            }
            .joined(separator: "&")
            .data(using: .utf8)
        }
    }
    
    extension CharacterSet { 
        static let urlQueryValueAllowed: CharacterSet = {
            let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
            let subDelimitersToEncode = "!$&'()*+,;="
    
            var allowed = CharacterSet.urlQueryAllowed
            allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
            return allowed
        }()
    }
    

    This checks for both fundamental networking errors as well as high-level HTTP errors. This also properly percent escapes the parameters of the query.

    Note, I used a name of Jack & Jill, to illustrate the proper x-www-form-urlencoded result of name=Jack%20%26%20Jill, which is “percent encoded” (i.e. the space is replaced with %20 and the & in the value is replaced with %26).


    See previous revision of this answer for Swift 2 rendition.

    0 讨论(0)
提交回复
热议问题