100 Days of SwiftUI
2026-05-26
Project 7, part 2
Building the basic iExpense app.
Starting with the most basic expense coding: name of the item, type — personal or business, and amount
Building a list we can delete from
- if you move code to another file, for example putting
structandclassdefinitions outside of theContentViewfile for neatness, be sure to addimport SwiftUIor the compiler will be mad at you - remember if you want to enable deletion, the
Listneeds to be powered by aForEach - also, the
ForEachis the home of the modifier that calls the deletion code (onDelete(perform: deletionFunction))
Working with Identifiable items in SwiftUI
- SwiftUI finds it difficult to keep track of items that may have all the same property values
- you spend
amount:5every day ontype:"personal"name:"lunch" - SwiftUI needs to know how it can identify each item uniquely
Listalready kinda knows how to handle this, but not everything does
- you spend
- you give your
structproperties aUUID—let id = UUID() - make the struct conform to
Identifiableprotocol, e.g.struct ExpenseItem: Identifiable { ... }- must have an
idparameter - adding that means you can remove the
idfrom theForEachbecause SwiftUI knows each item is already uniquely identified
- must have an
Making changes permanent with UserDefaults
- the UI is functional, but the app doesn’t really work yet, for example, adding expenses does nothing
- also, saving is only for the current session, so we need to save data between launches of the app
- this is where we use
JSONEncoderstuff. I will be looking this up every. single. time. - remember, just because you’ve save it, doesn’t mean it’s available to the app — your code needs to read in the stored data
Let me reiterate: I will be looking this up every. single. time
Final polish
- the
Add Expenseview just hangs out after you push “Save”, so we want to dismiss it. You do this with the@Environmentkeyword- “dismissing
AddViewis done by callingdismiss()on the environment when the time is right” - since we have a “Save” button, add
dismiss()to its actions
- “dismissing
Tomorrow we will have the challenge, and I hope some of it is to add the date of the expense 🙃