Swift Result Type
Main Idea
We use Result Type to let the user know that we can either obtain one variable or another but not both. Using result we can cover all possible cases of NetworkError
Example 1
struct ContentView: View {
@State private var output = ""
var body: some View {
Text(output)
.task {
await fetchReadings()
}
}
func fetchReadings() async {
let fetchTask = Task { () -> String in
let url = URL(string: "https://hws.dev/readings.json")!
let (data, _) = try await URLSession.shared.data(from: url)
let readings = try JSONDecoder().decode([Double].self, from: data)
return "Found \(readings.count) readings"
}
let result = await fetchTask.result
switch result {
case .success(let str):
output = str
case .failure(let error):
output = "Error: \(error.localizedDescription)"
}
}
}
Example 2
enum NetworkError: Error {
case badURL, requestFailed, unknown
}
struct ContentView: View {
var body: some View {
Text("Hello, World!")
.onAppear {
self.fetchData(from: "https://www.apple.com") { result in
switch result {
case .success(let str):
print(str)
case .failure(let error):
switch error {
case .badURL:
print("Bad URL")
case .requestFailed:
print("Netwrok problems")
case .unknown:
print("Unknown error ")
}
}
}
}
}
func fetchData(from urlString: String, completion: @escaping (Result<String, NetworkError>) -> Void) {
guard let url = URL(string: urlString) else {
completion(.failure(.badURL))
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
DispatchQueue.main.async {
if let data = data {
let stringData = String(decoding: data, as: UTF8.self)
completion(.success(stringData))
} else if error != nil {
completion(.failure(.requestFailed))
} else {
completion(.failure(.unknown))
}
}
}.resume()
}
}
Notes mentioning this note
Swift Unique Types
Main Idea
A complex data type holds multiple value at a time, grouping data together