Swift中的HTTP请求与POST方法

Swift中的HTTP请求与POST方法,post,swift,parameters,http-post,httprequest,Post,Swift,Parameters,Http Post,Httprequest,我试图在Swift中运行一个HTTP请求,向URL发送两个参数 例如: 链接:www.thisismylink.com/postName.php 参数: id = 13 name = Jack 最简单的方法是什么 我甚至不想看回复。我只想通过一个PHP文件发送它来对我的数据库执行更改。在Swift 3及更高版本中,您可以: let url = URL(string: "http://www.thisismylink.com/postName.php")! var request = URLRe

我试图在Swift中运行一个HTTP请求,向URL发送两个参数

例如:

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

参数:

id = 13
name = Jack
最简单的方法是什么


我甚至不想看回复。我只想通过一个PHP文件发送它来对我的数据库执行更改。

在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.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()
其中:

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
    }()
}
这将检查基本网络错误和高级HTTP错误。这也正确地转义了查询的参数

注意,我使用了
Jack&Jill
名称
,以说明
name=Jack%20%26%20Jill
的正确
x-www-form-urlencoded
结果,该结果为“百分比编码”(即空格替换为
%20
,值中的
&
替换为
%26



有关Swift 2格式副本,请参见。

以下是我在日志库中使用的方法:

此方法在Google表单中填充html表单

    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)

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

这里的所有答案都使用JSON对象。这给我们带来了问题
$this->input->post()
我们的Codeigniter控制器的方法。
CI_控制器
无法直接读取JSON。 我们使用这个方法在没有JSON的情况下完成它

func postRequest(){
//创建url对象
guard let url=url(字符串:yourURL)else{return}
//创建会话对象
让session=URLSession.shared
//使用url对象创建URLRequest对象
var-request=URLRequest(url:url)
//设置请求方法。重要信息:不要设置任何其他标题,如内容类型
request.httpMethod=“POST”//将http方法设置为POST
//在此处设置参数。替换为您自己的参数。
让postData=“param1_id=param1_value¶m2_id=param2_value”。数据(使用:.utf8)
request.httpBody=postData
//使用会话对象创建任务,以运行并返回完成处理程序
让webTask=session.dataTask(使用:请求,completionHandler:{数据,响应,错误)
保护错误==nil else{
打印(错误?.localizedDescription??“响应错误”)
返回
}
guard let serverData=data else{
打印(“服务器数据错误”)
返回
}
做{
如果让requestJson=try JSONSerialization.jsonObject(带:serverData,选项:.mutableContainers)作为?[String:Any]{
打印(“响应:\(请求JSON)”)
}
}抓住让我们回应错误{
打印(“创建响应正文时出现序列化错误:\(responseError.localizedDescription)”)
let message=String(字节:serverData,编码:.ascii)
打印(如有消息)
}
//运行任务
webTask.resume()
}

现在,您的CI_控制器将能够使用
$this->input->post('param1')
$this->input->post('param2')

获得
param1
param2

您不需要手动添加百分比编码。 使用
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
查询
将是一个正确转义的字符串:

key1=NeedToEscape%3和%26&key2=v%C3%A5l%C3%BC%C3%A9

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

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

现在,您可以发送请求。

FYI,如果您想执行实际请求(包括百分比转义、创建复杂请求、简化响应解析)从AfnDead的作者那里考虑使用,但是如果你只想做一个琐碎的<代码> POST <代码>请求,你可以使用上面的内容。谢谢Rob,这正是我所要寻找的。只不过是一个简单的帖子。很棒的答案!Alamofire在这方面没有更好,也不比 URLStuts更差。所有的网络API都是天生的。现在,如果你在寻找其他处理异步请求的优美方式,你可以考虑包装它们(或者是<代码> URLStuts< /Calp>请求或ALAOFRAE)。在异步中,自定义
操作
子类。或者您可以使用一些PromiseKit之类的PromiseKit库。@DeepBlue-我理解您的意思,但我尊重您的意见。如果出现问题,则默认失败是一个非常糟糕的主意。也许您可以执行
guard let url=…否则{fatalError(“无效url”)}
,但这是语法噪音,没有什么好处。你正在为一些不是最终用户运行时问题,而是编程问题错误的东西编写大量错误处理代码。这个类比是隐式展开的
@IBOutlet
引用。你是否编写了大量的
guard let label=…
>所有出口的代码?不。那太傻了。这里也一样。别误会我。如果有一些事情不是很明显,或者由于程序员无法控制的原因(比如解析JSON响应和/或处理网络错误)而失败,然后使用强制展开运算符是一个巨大的错误。绝对可以安全地展开它们。但是对于像
@IBOutlet
或这个URL示例这样的东西,添加语法噪音IMHO会适得其反。并且使用
else
子句来执行
保护
,该子句只返回
,隐藏任何底层i是的,这是一个非常糟糕的主意。我在你的代码中得到以下错误“数据无法读取,因为它的格式不正确。”我想您得到的是字符串格式的响应,您可以验证吗?我认为此解决方案中的问题是,您将参数作为json序列化传递,而web服务将作为formdata参数。解决方案中的参数是json,请与服务器确认是否需要表单数据,然后更改内容
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
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = Data(query.utf8)