State Management in SwiftUI

Jun 20 2024 · Swift 5.9, iOS 17.2, Xcode 15.2

Lesson 03: Leveraging Observation for Shared State Management

Extracting Logic Outside SwiftUI Using Observation Demo

Episode complete

Play next episode

Next

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Welcome to this video demo on adding a totals section to the list view in the budget-tracking app. By the end of this demo, you’ll understand how to display the total expenses and income in a way that makes the totaling logic testable outside of SwiftUI. Let’s get started!

Step 1: Implementing an Observable FinancialData Class

First, you’ll create a FinancialData class to encapsulate the list of financial entries and the logic to compute total expenses and income. This approach keeps the model layer clean and separates the business logic from the UI layer.

@Observable
final class FinancialData {
  var entries: [FinancialEntry] = []

  var totalExpenses: Double {
    entries.filter { $0.isExpense }.reduce(0) { $0 + $1.amount }
  }

  var totalIncome: Double {
    entries.filter { !$0.isExpense }.reduce(0) { $0 + $1.amount }
  }
}

Step 2: Integrating FinancialData Into BudgetTrackerApp

Next, you’ll integrate the FinancialData class into the app by adding it as a state property in the BudgetTrackerApp struct. This ensures that the financial data is available to be passed throughout the app.

  @State private var financialData = FinancialData()

Step 3: Updating ContentView to Use FinancialData

Now, you’ll update ContentView to use the FinancialData object instead of managing its own list of entries. This centralizes data management and prepares you to display the totals.

@Bindable var financialData: FinancialData
      ContentView(financialData: financialData)
#Preview {
  ContentView(financialData: FinancialData())
}
ForEach(financialData.entries) { entry in
  financialEntries: $financialData.entries)

Step 4: Adding a Totals Section to the List View

Finally, add a new section to the list view that displays the computed total expenses and income. This gives users a quick overview of their financial status.

Section(header: Text("Totals")) {
  HStack {
    Text("Total Expenses")
    Spacer()
    Text("$\(financialData.totalExpenses, specifier: "%.2f")")
      .foregroundColor(.red)
  }
  HStack {
    Text("Total Income")
    Spacer()
    Text("$\(financialData.totalIncome, specifier: "%.2f")")
      .foregroundColor(.green)
  }
}

Wrap-Up

And that’s it! You’ve now added a totals section to the budget-tracking app, improving its functionality and testability. Great job on finishing the demo!

See forum comments
Cinema mode Download course materials from Github
Previous: Intro to Observation in SwiftUI Next: Conclusion