Skip to content

Instantly share code, notes, and snippets.

@hmlongco
Created February 24, 2025 20:10
Show Gist options
  • Save hmlongco/9ed8f2e8f67ad267cfcbab6f6dbb2d80 to your computer and use it in GitHub Desktop.
Save hmlongco/9ed8f2e8f67ad267cfcbab6f6dbb2d80 to your computer and use it in GitHub Desktop.
Task cancellation.swift
// original code, intermediate variable
class SomeViewModel1: ObservableObject {
@Published var searchResults: [String] = []
private var currentSearchTask: Task<Void, Never>?
@MainActor
func search(_ query: String) {
currentSearchTask?.cancel()
let newTask = Task {
do {
try await Task.sleep(for: .milliseconds(500))
print("Starting to search!")
searchResults = Self.articleTitlesDatabase
.filter { $0.lowercased().contains(query.lowercased()) }
} catch {
print("Search was cancelled!")
}
}
currentSearchTask = newTask
}
static var articleTitlesDatabase: [String] {
[]
}
}
// revised code, direct assignment
class SomeViewModel2: ObservableObject {
@Published var searchResults: [String] = []
private var currentSearchTask: Task<Void, Never>?
@MainActor
func search(_ query: String) {
currentSearchTask?.cancel()
currentSearchTask = Task {
do {
try await Task.sleep(for: .milliseconds(500))
print("Starting to search!")
searchResults = Self.articleTitlesDatabase
.filter { $0.lowercased().contains(query.lowercased()) }
} catch {
print("Search was cancelled!")
}
}
}
static var articleTitlesDatabase: [String] {
[]
}
}
// preferred code, called from .task(id: text) { await viewModel.search(text) }
class SomeViewModel3: ObservableObject {
@Published var searchResults: [String] = []
@MainActor
func search(_ query: String) async {
do {
try await Task.sleep(for: .milliseconds(500))
print("Starting to search!")
searchResults = Self.articleTitlesDatabase
.filter { $0.lowercased().contains(query.lowercased()) }
} catch {
print("Search was cancelled!")
}
}
static var articleTitlesDatabase: [String] {
[]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment