Swift HTTP POST 合并请求
Swift HTTP POST request with Combine
在我的应用程序中,我使用 Combine 框架来发出网络请求,它可以很好地处理 GET 请求。但是我 运行 遇到了这个问题 POST 请求。
以下代码(没有 Combine)工作正常:
let data = ["statusTime": DateFormatter.iso8601Full.string(from: Date())]
let requestBody = try? JSONSerialization.data(withJSONObject: data, options: [])
let baseURL = "my-api.amazonaws.com"
let endpoint = "/my/endpoint"
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = baseURL
urlComponents.path = endpoint
let url = urlComponents.url!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = requestBody
request.addValue(authorizationToken, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("error: \(error)")
return
}
print("Response: \((response as! HTTPURLResponse).statusCode)")
}
task.resume()
我从上面的代码中得到了一个 200 的响应代码。
与 Combine 相同的代码:
let data = ["statusTime": DateFormatter.iso8601Full.string(from: Date())]
let requestBody = try? JSONSerialization.data(withJSONObject: data, options: [])
let baseURL = "my-api.amazonaws.com"
let endpoint = "/my/endpoint"
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = baseURL
urlComponents.path = endpoint
let url = urlComponents.url!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = requestBody
request.addValue(authorizationToken, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let cancellable = URLSession.shared
.dataTaskPublisher(for: request)
.print()
.sink(receiveCompletion: {
if let error = [=13=].error {
print("Failure: \(error)")
}
}, receiveValue: {
print("\([=13=])")
})
这是我收到的输出:
receive subscription: (DataTaskPublisher)
request unlimited
receive cancel
似乎以某种方式取消了使用 Combine 框架的请求?我使用了网络跟踪应用程序,我可以看到第一个请求(没有 Combine),但看不到第二个请求。
我查看了许多帖子和文档,但看不出我的代码有什么问题。我错过了什么?提前致谢。
我看到您正在创建 cancellable
,但您是否保留了对它的强烈引用?看起来您正在创建请求,然后可取消项超出范围并被释放,从而取消了请求。
在您的 class 中声明这样的内容:
var cancellables = Set<AnyCancellable>()
然后您隐式地将可取消存储为:
URLSession.shared // You don't hold on to the returned cancellable here
.dataTaskPublisher(for: request)
.print()
.sink(receiveCompletion: {
if let error = [=11=].error {
print("Failure: \(error)")
}
}, receiveValue: {
print("\([=11=])")
})
.store(in: &cancellables) // This puts the cancellable into the variables so it stays in scope
在我的应用程序中,我使用 Combine 框架来发出网络请求,它可以很好地处理 GET 请求。但是我 运行 遇到了这个问题 POST 请求。
以下代码(没有 Combine)工作正常:
let data = ["statusTime": DateFormatter.iso8601Full.string(from: Date())]
let requestBody = try? JSONSerialization.data(withJSONObject: data, options: [])
let baseURL = "my-api.amazonaws.com"
let endpoint = "/my/endpoint"
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = baseURL
urlComponents.path = endpoint
let url = urlComponents.url!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = requestBody
request.addValue(authorizationToken, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("error: \(error)")
return
}
print("Response: \((response as! HTTPURLResponse).statusCode)")
}
task.resume()
我从上面的代码中得到了一个 200 的响应代码。
与 Combine 相同的代码:
let data = ["statusTime": DateFormatter.iso8601Full.string(from: Date())]
let requestBody = try? JSONSerialization.data(withJSONObject: data, options: [])
let baseURL = "my-api.amazonaws.com"
let endpoint = "/my/endpoint"
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = baseURL
urlComponents.path = endpoint
let url = urlComponents.url!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = requestBody
request.addValue(authorizationToken, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let cancellable = URLSession.shared
.dataTaskPublisher(for: request)
.print()
.sink(receiveCompletion: {
if let error = [=13=].error {
print("Failure: \(error)")
}
}, receiveValue: {
print("\([=13=])")
})
这是我收到的输出:
receive subscription: (DataTaskPublisher)
request unlimited
receive cancel
似乎以某种方式取消了使用 Combine 框架的请求?我使用了网络跟踪应用程序,我可以看到第一个请求(没有 Combine),但看不到第二个请求。
我查看了许多帖子和文档,但看不出我的代码有什么问题。我错过了什么?提前致谢。
我看到您正在创建 cancellable
,但您是否保留了对它的强烈引用?看起来您正在创建请求,然后可取消项超出范围并被释放,从而取消了请求。
在您的 class 中声明这样的内容:
var cancellables = Set<AnyCancellable>()
然后您隐式地将可取消存储为:
URLSession.shared // You don't hold on to the returned cancellable here
.dataTaskPublisher(for: request)
.print()
.sink(receiveCompletion: {
if let error = [=11=].error {
print("Failure: \(error)")
}
}, receiveValue: {
print("\([=11=])")
})
.store(in: &cancellables) // This puts the cancellable into the variables so it stays in scope