Learn how to work with Xcode Previews in SwiftData App. SwiftData in combination with SwiftUI…
SwiftUI View Lifecycle: A Guide to onAppear, onDisappear, and Task
In this tutorial, we’ll explore the lifecycle events onAppear
, onDisappear
, and the asynchronous task
modifier in SwiftUI. These tools are crucial for managing view states and performing actions at key points in a view’s lifecycle or asynchronously loading data when a view appears. Let’s dive into each of these with clear examples and see how they enhance the functionality of a SwiftUI app.
Understanding onAppear
and onDisappear
onAppear
and onDisappear
are modifiers that you attach to views to perform actions when the views appear or disappear from the screen. They are particularly useful for starting or stopping processes that should only run when a view is visible to the user.
Example: Stopwatch
Imagine a simple stopwatch app. We use onAppear
to start the timer when the view comes into focus and onDisappear
to pause the timer when the user navigates away.
struct StopwatchView: View {
@State private var secondsElapsed = 0
@State private var timer: Timer?
@State private var showView = false
var body: some View {
Button("Show View") {
showView = true
}
.popover(isPresented: $showView) {
VStack {
Text("Time: \(secondsElapsed) seconds")
.font(.largeTitle)
.padding()
Button("Reset") {
secondsElapsed = 0
}
}
.onAppear {
print(".onAppear fired")
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
secondsElapsed += 1
}
}
.onDisappear {
print(".onDisappear fired")
timer?.invalidate()
timer = nil
secondsElapsed = 0
}
}
}
}
In this StopwatchView
, the timer starts counting when the view appears and stops counting when it disappears, preventing unnecessary resource usage.
Understanding task
The task
modifier is used for performing asynchronous operations that are linked to a view’s lifecycle. It’s especially useful when you need to load data from external sources as soon as the view appears.
Example: Posts Data Fetcher
Hereβs a simple view that fetches posts data asynchronously when it appears on the screen:
struct Post: Codable {
let userID, id: Int
let title, body: String
enum CodingKeys: String, CodingKey {
case userID = "userId"
case id, title, body
}
}
typealias Posts = [Post]
struct PostsView: View {
@State private var requestInfo = "Loading weather data..."
var body: some View {
Text(requestInfo)
.padding()
.task {
await loadDataFromServer()
}
}
func loadDataFromServer() async {
do {
let url = URL(string: "https://jsonplaceholder.typicode.com/posts")!
let (data, _) = try await URLSession.shared.data(from: url)
let posts = try? JSONDecoder().decode(Posts.self, from: data)
requestInfo = "The first post title:\n\(posts?.first?.title ?? "Nothing found")\n\nThe last post title:\n\(posts?.last?.title ?? "Nothing found")"
} catch {
requestInfo = "Failed to load data"
}
}
}
This PostsView
initiates an asynchronous task to fetch data when the view appears. Using task
, we ensure that the network request is automatically canceled if the view disappears before the request completes, thus handling resources efficiently.
Conclusion
Understanding and effectively utilizing onAppear
, onDisappear
, and task
in SwiftUI are fundamental in creating responsive and efficient iOS apps. These tools allow to control the execution of code based on the visibility of views and manage asynchronous operations in a way that is tightly integrated with the view’s lifecycle. This approach ensures that your app behaves predictably and conservatively uses resources, enhancing the user experience.