100 days of swiftui: 37
https://www.hackingwithswift.com/100/swiftui/37
제목, 종류, 값을 입력하여 지출 내역 목록을 작성할 수 있는 앱을 만들었다. 아래는 구현하면서 기억할 만한 배운 점을 작성했다.
UUID로 각 인스턴스의 id를 자동으로 고유하게 설정함으로써 Identifiable 프로토콜을 만족시킬 수 있다. 그러면 swift는 각자가 고유함을 알게 되고 ForEach에서도 id를 설정하지 않아도 된다.
struct ExpenseItem: Identifiable {
let id = UUID()
let name: String
let type: String
let amount: Int
}
@Observable
class Expenses {
var items = [ExpenseItem]()
}
struct ContentView: View {
@State private var expenses = Expenses()
var body: some View {
NavigationStack {
List {
ForEach(expenses.items) { item in
Text("\(item.name)")
}
.onDelete(perform: { indexSet in
removeAtOffset(at: indexSet)
})
}
// ...
코드 파일
https://github.com/treesofgroo/Ios-IExpense/commit/98caa3ff1ac5fcac34e5281051510a31060dd458
앱이 종료되고 다시 켜져도 이전에 기록한 정보를 기억하도록 UserDefaults 저장소를 활용했다.
이곳에 구조체인 struct를 저장하기 위해선 우선 Codable 프로토콜을 만족시켜야 한다.
이때 let으로 설정한 id를 var로 변환할 수 있게 설정해야 한다.
struct ExpenseItem: Identifiable, Codable {
var id = UUID()
let name: String
let type: String
let amount: Double
}
그리고 앱이 켜지면 이전에 저장된 Items
가 있는지 확인하고, 있다면 이전 정보를 불러오고 없다면 빈 배열로 정의한다. 정보를 불러올 때는 UserDefaults에서 디코딩해야 한다.
// @Observable class인 Expenses
init() {
if let savedItems = UserDefaults.standard.data(forKey: "Items") { if let decodedItems = try? JSONDecoder().decode([ExpenseItem].self, from: savedItems) {
items = decodedItems
return
}
}
items = []
}
마지막으로 item이 추가되거나 삭제될 때마다 변화를 감지하고 이를 UserDefaults에 업데이트 시켜야 한다. 마찬가지로 정보를 저장할 때도 인코딩하여 데이터를 가공하여 저장하는 과정이 필요하다.
@Observable
class Expenses {
var items = [ExpenseItem]() {
didSet {
if let encoded = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(encoded, forKey: "Items")
}
}
}
// ...
코드 파일
https://github.com/treesofgroo/Ios-IExpense/commit/45cd765e46b7037b1f0e3e2a3a13cdaa71d61272
![]() | ![]() |
---|