我正在构建一个小应用程序,它可以使用 Alamofire 与 jsonbin API 进行通信。他们的 API 文档涵盖了使用 Python 在 Python 中广泛“放置”或“更新”JSON 文件数据。我正在努力在 Swift 5 中做到这一点。
我的问题是当我尝试使用 put 命令将数据发送到特定文件时。见代码:
import AlamoFire
func sendData()
{
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"X-Master-Key": "x-x-x-x-x-x-x-x",
"X-Bin-Meta": "false"
]
let queue = DispatchQueue(label: "com.app.name", qos: .background, attributes: .concurrent)
do{
var testData = [
"title": "My Test Task",
"date": "My Date",
"complete": "Completion Status",
"assignee": "Bob Jones"
]
AF.request("https://api.jsonbin.io/v3/b/x-x-x-x-x-x-x", method: .put, parameters: testData, headers: headers).validate().responseJSON(queue: queue) { response in
switch response.result {
case .success(_):
print("Success!")
case .failure(let error):
print(error)
}
}
}
catch
{
print("Error occured.")
}
}
我正在尝试发送一个简单的 JSON 结构。我收到的错误是这样的:
esponseValidationFailed(reason: Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(code: 400))
他们的 API 文档说错误 400 通常意味着:
您需要将 Content-Type 设置为 application/json
提供的 Bin ID 无效
Bin(JSON数据)不能为空
我已验证所有这些要求都是正确的。
这里是根据他们的文档运行的 Python 代码:
import requests
url = 'https://api.jsonbin.io/v3/b/x-x-x-x-x-x'
headers = {
'Content-Type': 'application/json',
'X-Master-Key': 'x-x-x-x-x-x-x'
}
data = {"sample": "Hello World"}
req = requests.put(url, json=data, headers=headers)
print(req.text)
我有什么遗漏的吗?数据类型不同吗?
testData
Swift 变量与 data
Python 变量不同吗?我如何使用 Swift 和 Alamofire 5 将数据“放入”RESTful API?
谢谢!
您当前的参数不是以 JSON 形式发送,而是以 url 编码形式发送。
可以使用Alamofire的cURL描述工具方法来查看它是如何发送的:
AF.request("https://api.jsonbin.io/v3/b/x-x-x-x-x-x-x",
method: .put,
parameters: testData,
headers: headers)
.cURLDescription { print("JSONBIN curl: \($0)") }
.validate()
.responseJSON(queue: queue) { response in
switch response.result {
case .success(_):
print("Success!")
case .failure(let error):
print(error)
}
}
你会得到:
JSONBIN curl: $ curl -v \
-X PUT \
-H "Accept-Language: fr-US;q=1.0" \
-H "User-Agent: Alamofired/1.0 (ZzZ; build:1; iOS 16.4.0) Alamofire/5.4.0" \
-H "Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8" \
-H "Content-Type: application/json" \
-H "X-Bin-Meta: false" \
-H "X-Master-Key: x-x-x-x-x-x-x-x" \
-d "assignee=Bob%20Jones&complete=Completion%20Status&date=My%20Date&title=My%20Test%20Task" \
"https://api.jsonbin.io/v3/b/x-x-x-x-x-x-x"
重要的部分是
-d "assignee=Bob%20Jones&complete=Completion%20Status&date=My%20Date&title=My%20Test%20Task"
所以你需要告诉以 JSON 形式发送参数:
AF.request("https://api.jsonbin.io/v3/b/x-x-x-x-x-x-x",
method: .put,
parameters: testData,
encoder: JSONParameterEncoder.default,
headers: headers)
.cURLDescription { print("JSONBIN curl: \($0)") }
.validate()
.responseJSON(queue: queue) { response in
switch response.result {
case .success(_):
print("Success!")
case .failure(let error):
print(error)
}
}
然后,cURL 输出参数行为:
-d "{\"date\":\"My Date\",\"title\":\"My Test Task\",\"complete\":\"Completion Status\",\"assignee\":\"Bob Jones\"}" \
与您的代码无关,但是: 不需要
do
/catch
,没有try
,如果真的有error
,而不仅仅是try
,建议打印print("Error occured.")
。但是print("Error occurred: \(error)")
。
此外,
responseJSON()
已被弃用,取而代之的是 Codable
和 responseDecodable(of:)
。如果您仍然想使用 JSONSerialization
(在 responseJSON()
内部调用),请使用 responseData()
并自己调用它。