基本上,我需要向正在寻找"value"
的参数值的API发送POST请求,我的Swift应用程序中有一个名为testPOST的变量,其中包含API所寻找的值:< / p>
我无法理解以下代码为何不起作用?
fileprivate func fetchJSON(){
var urlString = URLRequest(url: URL(string: "https://example.com/example/example.php")!)
guard let url = URL(string: urlString) else { return }
urlString.httpMethod = "POST"
let postString = "value=\(testPOST)"
URLRequest.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with: url) { (data, _, error) in
DispatchQueue.main.async {
if let error = error {
print("Failed to fetch data from url", error)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
// Swift 4.1
self.structure = try decoder.decode([ScheduleStructure].self, from: data)
self.tableView.reloadData()
} catch let jsonError {
print("Failed to decode json", jsonError)
}
}
}.resume()
}
更新:
我没有收到任何错误消息,但是我也没有收到任何JSON数据,ScheduleStructure是我拥有的可编码结构,但似乎无法读取。
导入UIKit
struct ScheduleStructure: Codable {
let customer: String
let PickedUpNUM: String
let DeliveryNUM: String
}
我只需要一种将值发布到API并使其返回JSON数据的方法。我唯一遇到的问题是从应用发送数据并返回数据。
答案 0 :(得分:3)
将函数的开头更改为
guard let url = URL(string: "https://example.com/example/example.php") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
let postString = "value=\(testPOST)"
request.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data, _, error) in
您两次创建了url对象,并将请求视为字符串
答案 1 :(得分:1)
您应该随时接受Joakim’s answer,它标识了句法问题,但是我想再说一遍。具体来说,如果testPOST
包含任何保留字符(例如空格,&
,+
等),您的请求将失败或无法正常工作。除非您知道testPOST
绝不能包含任何此类字符,否则应在构建请求时对值进行百分比编码,例如:
func fetchJSON() {
guard
let url = URL(string: "https://example.com/example/example.php"),
let value = testPOST.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)
else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "value=\(value)".data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, _, error in
DispatchQueue.main.async {
// ...
}
}.resume()
}
哪里
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
}()
}
顺便说一句,最好的做法(虽然通常不是必需的)是设置一些标头,特别是Content-Type
(指定请求的编码方式)和Accept
(客户端期望响应如何)编码)。
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
您的Web服务显然没有考虑这些标头,但是许多Web服务却在考虑。另外,它使您的代码意图明确。