Using Combine With SwiftUI for State Management
Written by Team Kodeco
Combine is a functional reactive programming framework from Apple. It provides a declarative Swift API for processing values over time. These values can represent user interface events, network responses, scheduled events and many other kinds of asynchronous data.
When used with SwiftUI, Combine helps you write clean, reactive code that responds to changes in state over time. The core of Combine is publishers and subscribers: publishers emit events, and subscribers listen for those events.
Note: This example uses a hardcoded list of jokes. In a real application, you would replace this with network code to fetch jokes from a server.
Fetching Jokes: an Example
In this example, you’ll create a simple application that fetches a random joke from an API every time a button is clicked. You’ll use Combine to handle the networking and SwiftUI to display the result.
import SwiftUI
import Combine
struct ContentView: View {
@StateObject private var jokeFetcher = JokeFetcher()
var body: some View {
VStack {
Text(jokeFetcher.joke)
.padding()
Button("Fetch Joke") {
jokeFetcher.fetchJoke()
}
}
.onAppear {
jokeFetcher.fetchJoke()
}
}
}
class JokeFetcher: ObservableObject {
@Published var joke: String = ""
private var cancellable: AnyCancellable?
private let jokes = [
"Why don't scientists trust atoms? Because they make up everything!",
"Why did the bicycle fall over? Because it was two tired!",
"Why don't some animals play cards? Because they are afraid of cheetahs!",
"Why did the scarecrow win an award? Because he was outstanding in his field!"
]
func fetchJoke() {
// Networking code here
// Update `joke` with the result
if let randomJoke = jokes.randomElement() {
joke = randomJoke
}
}
deinit {
cancellable?.cancel()
}
}
In the above code:
-
JokeFetcher
is anObservableObject
that simulates the fetching of a joke from an API. It has a@Published
propertyjoke
which stores the fetched joke. Every timejoke
is updated, SwiftUI automatically triggers a UI update. -
fetchJoke()
is a method that randomly selects a joke from thejokes
array and assigns it to thejoke
property. - In
ContentView
, aJokeFetcher
object is created using the@StateObject
property wrapper which ensures the object is only created once and persists across view updates. - The
Text
view is used to display the joke, and theButton
triggers a new joke fetch when clicked. - The
onAppear
modifier is used to fetch a joke when the view first appears, ensuring there’s a joke displayed when the app launches.
Your preview should look like this:
To sum up, Combine is a powerful framework that can greatly simplify state management in SwiftUI. By integrating Combine with SwiftUI’s ObservableObject
and StateObject
, you can create dynamic and reactive UIs that handle complex, asynchronous events with ease.