Swift: Networking: Simple Request with Query
This article builds on $linktoid[art_0017]$.
Performing network communication in Swift is enabled using URLSession. A very simple request can be implemented with the asynchronous method `data(from: URL)` using just a couple of code lines.
Parameters for the request can be sent with query parameters. Use `URLComponents` and `URLQueryItem` for that. These types handle conversion of special characters and save you from implementing complicated checks of edge cases.
For easy testing the Python package FastAPI provides a very simple and quick means. That way handling network requests can be tested in the simulator while the server can be started on the developer computer.
Preparing a FastAPI Server
To handle query parameters one can declare function arguments. They are automatically treated as query parameters by FastAPI. For this test the function just returns an upper-cased string of the argument.
@app.get("/text/upcase") def read_text_upcase(string: str): return {"result": string.upper()}
Performing the Network Request in Swift
To add the query parameter to the URL, use `URLComponents` and `URLQueryItem` like shown below. It is strongly recommended to not add the query parameters using direct string manipulation of the URL.
import SwiftUI struct SimpleRequestWithQueryView: View { @State private var text: String = "a text" @State private var response: String = "-" @State private var errorInfo: String = "-" var body: some View { VStack { Text("Simple Request with Query") .font(.largeTitle) Form { TextField("Enter text", text: $text) Button(action: { sendRequest() }, label: { Label("Send", systemImage: "paperplane") }) LabeledContent("Response", value: response) LabeledContent("Error Info", value: errorInfo) } } } private func sendRequest() { Task { do { guard let url = URL(string: "http://localhost:8000/text/upcase") else { return } guard var comps = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return } let qi = URLQueryItem(name: "string", value: text) comps.queryItems = [qi] guard let urlq = comps.url else { return } let (data, resp) = try await URLSession.shared.data(from: urlq) if let httpResp = resp as? HTTPURLResponse { if httpResp.statusCode != 200 { self.errorInfo = "Error: Expected 200" return } } guard let string = String(data: data, encoding: .utf8) else { return } self.response = string self.errorInfo = "-" } catch { self.response = "-" self.errorInfo = "\(error.localizedDescription)" } } } } #Preview { SimpleRequestWithQueryView() }
