使用POST方法在Swift中进行HTTP请求

时间:2014-10-14 15:47:14

标签: post swift parameters http-post httprequest

我试图在Swift中运行HTTP请求,将2个参数发送到URL。

示例:

链接:www.thisismylink.com/postName.php

PARAMS:

id = 13
name = Jack

最简单的方法是什么?

我甚至不想阅读回复。我只是想发送它来通过PHP文件对我的数据库进行更改。

7 个答案:

答案 0 :(得分:348)

在Swift 3及更高版本中,您可以:

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.percentEscaped().data(using: .utf8)

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

其中:

extension Dictionary {
    func percentEscaped() -> String {
        return map { (key, value) in
            let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            return escapedKey + "=" + escapedValue
        }
        .joined(separator: "&")
    }
}

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

这将检查基本网络错误以及高级HTTP错误。这也正确地百分比转义查询的参数。

注意,我使用了name Jack & Jill来说明x-www-form-urlencoded name=Jack%20%26%20Jill的正确%20结果,即“百分比编码”(即空格被替换为&并且值中的%26将替换为{{1}})。


有关Swift 2的演绎,请参阅previous revision of this answer

答案 1 :(得分:43)

Swift 3和swift 4

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

答案 2 :(得分:8)

这是我在日志记录库中使用的方法:https://github.com/goktugyil/QorumLogs

此方法填写Google表单中的html表单。

      mongo.removeApiCall("uri11").then(function() {
            return mongo.removeApiCall("uri12");
        }).then(function() {
            return mongo.insertApiCall("uri11", "type1", 2, "domain", "target", "url", "phrase", "d1|d1", data);
        }).then(function() {
            return mongo.insertApiCall("uri12", "type1", 2, "domain", "target", "url", "phrase", "d1|d2");
        }).then(function() {
            return mongo.insertApiCall("uri12", "type2", 2, "domain", "target", "url", "phrase", "d1|d2")
        }).then(function() {
            return mongo.removeApiCall("uri12", "type1", null, null, null, null, null, false);
        }).then(function() {
            return mongo.findApiCall("uri12");
        }).then(function(result) {
            assert.isArray(result);
            assert.equal(1, result.length, "Array length is " + result.length);
            assert.equal("type2", result[0].apiType);
        }).then(function() {
            return mongo.findApiCall("uri11");
        }).then(function(result2) {
            assert.isArray(result2);
            assert.equal(1, result2.length);
            return mongo.removeApiCall("uri11");
        }).then(function() {
            return mongo.removeApiCall("uri12");
        }).then(function() {
            done();
        });

答案 3 :(得分:3)

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

答案 4 :(得分:3)

适用于任何寻求以干净方式在Swift 5中编码POST请求的人。

您无需手动添加百分比编码。 使用URLComponents创建GET请求URL。然后使用该URL的query属性正确获取转义查询字符串的百分比。

let url = URL(string: "https://example.com")!
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!

components.queryItems = [
    URLQueryItem(name: "key1", value: "NeedToEscape=And&"),
    URLQueryItem(name: "key2", value: "vålüé")
]

let query = components.url!.query

query将是正确转义的字符串:

  

key1 = NeedToEscape%3DAnd%26&key2 = v%C3%A51l%C3%BC%C3%A9

现在,您可以创建一个请求并将查询用作HTTPBody:

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = Data(query.utf8)

现在您可以发送请求。

答案 5 :(得分:1)

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

答案 6 :(得分:0)

这里的所有答案都使用JSON对象。这给我们带来了问题 list_of_df = ['NPSFeedback', 'courses','test'] temp = '' for df in list_of_df: print(new_df) temp = df + '.json' #print(temp) temp = pd.read_json(temp) temp = temp.replace('', np.nan) df = temp.copy() del temp df 我们的Codeigniter控制器的方法。 $this->input->post()无法直接读取JSON。 我们使用这种方法在没有JSON的情况下

CI_Controller

现在,您的CI_Controller将能够使用fun 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() param1来获取param2$this->input->post('param1')