37: IEpense, part 2

그루두·2024년 6월 1일
0

100 days of SwiftUI

목록 보기
45/108
post-thumbnail

100 days of swiftui: 37
https://www.hackingwithswift.com/100/swiftui/37

제목, 종류, 값을 입력하여 지출 내역 목록을 작성할 수 있는 앱을 만들었다. 아래는 구현하면서 기억할 만한 배운 점을 작성했다.

UUID

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

결과물

코드 파일
https://github.com/treesofgroo/Ios-IExpense

profile
계속 해보자

0개의 댓글

관련 채용 정보