在 SwiftUI 中的简单 URLSession POST 请求期间添加 ProgressView
Add a ProgressView during a simple URLSession POST request in SwiftUI
我想在一个简单的 URL POST 请求过程中显示进度视图。我想要做的是在 requestTest
函数过程中将按钮变成 ProgressView
微调器(通常是默认设置)。请求完成后,进度视图消失并变回按钮。
这是代码。
struct ContentView: View {
@State private var tweetID = ""
@State private var tweetStatus = ""
@State private var response = ""
@State var showAlert = false
@State var sendToWebhook = false
var body: some View {
NavigationView {
Form {
Section(footer: Text("Test")) {
TextField("Field to place response data", text: $response)
TextEditor( text: $tweetStatus)
.frame(height: 100)
}
Section {
Button("Get Data") {
// Where progress should start before function
ProgressView("Test", value: 100, total: 100)
requestTest() { results in
response = results
if response == "No Data!" {
showAlert = true
}
}
}
if self.requestTest {
ProgressView()
}
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Tweet Sent"), message: Text("Your Tweet is sent! Your Tweet ID is shown in the field"), dismissButton: .default(Text("OK")))
}
}
}
func requestTest(completion: @escaping(String) -> ()) {
if let url = URL(string: "https://requestbin.net/r/ag4ipg7n") {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
components.queryItems = [ URLQueryItem(name: "TweetID", value: response),
URLQueryItem(name: "Status", value: tweetStatus)]
if let query = components.url!.query {
request.httpBody = Data(query.utf8)
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data,
let apiResponse = String(data: data, encoding: .utf8) {
// IF Completed, these actions are shown below
completion(apiResponse)
self.showAlert = true
tweetStatus = ""
} else {
completion("No Data!")
}
}
task.resume()
}
}
}
我想如果我尝试像 if self.requestTest { ProgressView() }
那样做,但无济于事,因为它抛出了一个错误 Cannot convert value of type '(@escaping (String) -> ()) -> ()' to expected condition type 'Bool'
。
有办法吗?
有多种方法可以满足您的要求。这是
只有一种方法:
struct ContentView: View {
@State private var tweetID = ""
@State private var tweetStatus = ""
@State private var response = ""
@State var showAlert = false
@State var sendToWebhook = false
@State var inProgress = false // <--- here
var body: some View {
NavigationView {
Form {
Section(footer: Text("Test")) {
TextField("Field to place response data", text: $response)
TextEditor( text: $tweetStatus)
.frame(height: 100)
}
Section {
Button("Get Data") {
inProgress = true // <--- here
requestTest() { results in
inProgress = false // <--- here
response = results
if response == "No Data!" {
showAlert = true
}
}
}
if inProgress { // <--- here
ProgressView()
}
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Tweet Sent"), message: Text("Your Tweet is sent! Your Tweet ID is shown in the field"), dismissButton: .default(Text("OK")))
}
}
}
我想在一个简单的 URL POST 请求过程中显示进度视图。我想要做的是在 requestTest
函数过程中将按钮变成 ProgressView
微调器(通常是默认设置)。请求完成后,进度视图消失并变回按钮。
这是代码。
struct ContentView: View {
@State private var tweetID = ""
@State private var tweetStatus = ""
@State private var response = ""
@State var showAlert = false
@State var sendToWebhook = false
var body: some View {
NavigationView {
Form {
Section(footer: Text("Test")) {
TextField("Field to place response data", text: $response)
TextEditor( text: $tweetStatus)
.frame(height: 100)
}
Section {
Button("Get Data") {
// Where progress should start before function
ProgressView("Test", value: 100, total: 100)
requestTest() { results in
response = results
if response == "No Data!" {
showAlert = true
}
}
}
if self.requestTest {
ProgressView()
}
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Tweet Sent"), message: Text("Your Tweet is sent! Your Tweet ID is shown in the field"), dismissButton: .default(Text("OK")))
}
}
}
func requestTest(completion: @escaping(String) -> ()) {
if let url = URL(string: "https://requestbin.net/r/ag4ipg7n") {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
components.queryItems = [ URLQueryItem(name: "TweetID", value: response),
URLQueryItem(name: "Status", value: tweetStatus)]
if let query = components.url!.query {
request.httpBody = Data(query.utf8)
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data,
let apiResponse = String(data: data, encoding: .utf8) {
// IF Completed, these actions are shown below
completion(apiResponse)
self.showAlert = true
tweetStatus = ""
} else {
completion("No Data!")
}
}
task.resume()
}
}
}
我想如果我尝试像 if self.requestTest { ProgressView() }
那样做,但无济于事,因为它抛出了一个错误 Cannot convert value of type '(@escaping (String) -> ()) -> ()' to expected condition type 'Bool'
。
有办法吗?
有多种方法可以满足您的要求。这是 只有一种方法:
struct ContentView: View {
@State private var tweetID = ""
@State private var tweetStatus = ""
@State private var response = ""
@State var showAlert = false
@State var sendToWebhook = false
@State var inProgress = false // <--- here
var body: some View {
NavigationView {
Form {
Section(footer: Text("Test")) {
TextField("Field to place response data", text: $response)
TextEditor( text: $tweetStatus)
.frame(height: 100)
}
Section {
Button("Get Data") {
inProgress = true // <--- here
requestTest() { results in
inProgress = false // <--- here
response = results
if response == "No Data!" {
showAlert = true
}
}
}
if inProgress { // <--- here
ProgressView()
}
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Tweet Sent"), message: Text("Your Tweet is sent! Your Tweet ID is shown in the field"), dismissButton: .default(Text("OK")))
}
}
}