Post

Replies

Boosts

Views

Activity

Reply to Add a ProgressView during a simple URLSession POST request in SwiftUI
In your code, requestTest is a name of a function. Using a function name in a condition of if-statement does not make sense. To use if-statement, you need an expression returning Bool. Please try something like this: import SwiftUI 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 isRequestInProgress: Bool = 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 //↓Writing a View in an action closure does not make sensse //ProgressView("Test", value: 100, total: 100) requestTest() { results in response = results if response == "No Data!" { showAlert = true } } } if isRequestInProgress { //<- 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) } self.isRequestInProgress = true //<- let task = URLSession.shared.dataTask(with: request) { data, response, error in //↓ defer { DispatchQueue.main.async { self.isRequestInProgress = false } } 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() } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Use placeholder app icon in view in Swift Playgrounds 4
I'm not sure how iOS handles that, but it seems the iOS App Icon resource with name AppIcon in Assets.xcassets is handled specially by iOS and you cannot access it from inside your app. If you want to use it as Image("..."), you may need to create an Image Set resource with another name than AppIcon, and copy the same image into it.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Publishers.CombineLatest in SwiftUI
To utilize Combine well, you may need to know what are (or should be or can be) publisher. @State variables cannot be publishers without some additional code. To make publishers easily, you can work with ObservableObject with @Published variables: import SwiftUI import Combine class ValidateLogin { let user: String let pass: String init(user: String, pass: String) { self.user = user self.pass = pass } func validateMe() -> Bool { return user.count > 3 && pass.count > 3 } } class MyContent: ObservableObject { @Published var userText: String = "" @Published var passText: String = "" } struct ContentView: View { @StateObject var content = MyContent() @State var canSave: Bool = false @State var contentSubscriber: AnyCancellable? var body: some View { ZStack { VStack { TextField("Username", text: $content.userText) { } SecureField("Password", text: $content.passText) { } }.padding(.horizontal, 20.0) }.onAppear { self.contentSubscriber = self.content.$userText .combineLatest(content.$passText) .sink {userText, passText in let validateLogin = ValidateLogin(user: userText, pass: passText) self.canSave = validateLogin.validateMe() } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22