Swift 并发 UIButton
Swift Concurrency UIButton
是否可以在 UIKit 中对 POST HTTP 请求使用 async/await,即来自 UIButton
的请求?
我可以收到发送的请求,但它立即崩溃了。使用 URLSession
完美工作,以此作为学习经验。
lazy var buttonTest: UIButton = {
let button = UIButton()
button.addTarget(self, action: #selector(testAsyncTwo), for: .touchUpInside)
return button
}()
@objc func testAsync() async throws {
let date = Date()
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateString = df.string(from: date)
let json: [String: Any] = ["item": "1",
"time": "\(dateString)"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
guard let url = URL(string: "https://myapiendpoint.com/api/") else { fatalError("Missing URL") }
var urlRequest = URLRequest(url: url)
let token: String = "mySecretKey"
urlRequest.setValue("Token \(token)", forHTTPHeaderField: "Authorization")
urlRequest.httpMethod = "POST"
urlRequest.setValue("\(String(describing: jsonData?.count))", forHTTPHeaderField: "Content-Length")
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.httpBody = jsonData
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard (response as? HTTPURLResponse)?.statusCode == 200 else { fatalError("Error while fetching data") }
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON) //Code after Successfull POST Request
}
}
非常感谢!
崩溃与您的 URLSession
代码无关。问题是您已将按钮的选择器声明为异步抛出函数。这与 @objc
选择器不兼容。
替换:
@objc func testAsync() async throws {
...
}
与:
@objc func didTapButton(_ sender: Any) {
Task {
try await testAsync()
}
}
func testAsync() async throws {
...
}
主要观察结果是 @objc
方法不是异步函数。我还会给按钮处理程序一个 sender
参数和一个更具描述性的名称,以遵循既定的约定并一目了然地表明它正在处理按钮点击。
显然,执行此操作时,您还必须更改 #selector
引用:
button.addTarget(self, action: #selector(didTapButton(_:)), for: .touchUpInside)
是否可以在 UIKit 中对 POST HTTP 请求使用 async/await,即来自 UIButton
的请求?
我可以收到发送的请求,但它立即崩溃了。使用 URLSession
完美工作,以此作为学习经验。
lazy var buttonTest: UIButton = {
let button = UIButton()
button.addTarget(self, action: #selector(testAsyncTwo), for: .touchUpInside)
return button
}()
@objc func testAsync() async throws {
let date = Date()
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateString = df.string(from: date)
let json: [String: Any] = ["item": "1",
"time": "\(dateString)"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
guard let url = URL(string: "https://myapiendpoint.com/api/") else { fatalError("Missing URL") }
var urlRequest = URLRequest(url: url)
let token: String = "mySecretKey"
urlRequest.setValue("Token \(token)", forHTTPHeaderField: "Authorization")
urlRequest.httpMethod = "POST"
urlRequest.setValue("\(String(describing: jsonData?.count))", forHTTPHeaderField: "Content-Length")
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.httpBody = jsonData
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard (response as? HTTPURLResponse)?.statusCode == 200 else { fatalError("Error while fetching data") }
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON) //Code after Successfull POST Request
}
}
非常感谢!
崩溃与您的 URLSession
代码无关。问题是您已将按钮的选择器声明为异步抛出函数。这与 @objc
选择器不兼容。
替换:
@objc func testAsync() async throws {
...
}
与:
@objc func didTapButton(_ sender: Any) {
Task {
try await testAsync()
}
}
func testAsync() async throws {
...
}
主要观察结果是 @objc
方法不是异步函数。我还会给按钮处理程序一个 sender
参数和一个更具描述性的名称,以遵循既定的约定并一目了然地表明它正在处理按钮点击。
显然,执行此操作时,您还必须更改 #selector
引用:
button.addTarget(self, action: #selector(didTapButton(_:)), for: .touchUpInside)