참고 프로젝트 개요
- MVVM 구조
- SwiftUI
-ToDO 리스트 프로젝트
UserDefaults에 데이터 저장
// ViewModel.swift
class ListViewModel: ObservableObject {
@Published var items: [ItemModel] = [] {
//ItemModel은 두개의 String과 하나의 Bool로 구성되어 있습니다.
didSet {
//items 값이 변화하면 감지하면 saveItem 메소드를 실행합니다.
saveItem()
}
}
let itemsKey: String = "items_list"
func saveItem() {
if let encodedData = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(encodedData, forKey: itemsKey)
}
}
}
saveItem이 UserDefaults를 사용하는 예시인데 Model을 그냥 다룰 수는 없기 때문에 데이터를 Json으로 다루고 저장합니다. 코드에서는 try와 JSONEncoder를 사용하여 items에 데이터가 존재하면 USerDefaults에 키 값으로 itemsKey에 데이터를 저장하도록 되어 있습니다.
여기서 forKey는 String이 들어가야 하며 오타 등으로 혼란이 발생하는 것을 방지하기 위해 itemsKey라는 변수를 생성하여 이용하였습니다.
UserDefaults에서 데이터 읽어오기
class ListViewModel: ObservableObject {
@Published var items: [ItemModel] = [] {
didSet {
saveItem()
}
}
let itemsKey: String = "items_list"
init() {
getItems()
}
func getItems() {
guard
let data = UserDefaults.standard.data(forKey: itemsKey),
let savedItems = try? JSONDecoder().decode([ItemModel].self, from: data)
else { return }
self.items = savedItems
}
}
init을 통해 getItems 메소드를 이용하여 데이터를 불러옵니다.
안에서는 UserDefaults.standard.data(forKey: )로 키에 해당하는 data를 가져올 수 있습니다. 가져온 data는 JsonDecoder를 통하여 ItemModel로 디코드 합니다. guard를 여러줄에 걸쳐 사용함으로써 줄마다 guard와 else return을 사용하는 걸 줄이는 기술을 볼 수 있습니다. 또한, items에 이렇게 불러워진 복사 합니다.
전체 코드
class ListViewModel: ObservableObject {
@Published var items: [ItemModel] = [] {
didSet {
saveItem()
}
}
let itemsKey: String = "items_list"
init() {
getItems()
}
func getItems() {
guard
let data = UserDefaults.standard.data(forKey: itemsKey),
let savedItems = try? JSONDecoder().decode([ItemModel].self, from: data)
else { return }
self.items = savedItems
}
func deleteItem(indexSet: IndexSet) {
items.remove(atOffsets: indexSet)
}
func moveItem(from: IndexSet, to: Int) {
items.move(fromOffsets: from, toOffset: to)
}
func addItem(title: String) {
let newItem = ItemModel(title: title, isCompleted: false)
items.append(newItem)
}
func updateItem(item: ItemModel) {
if let index = items.firstIndex(where: { $0.id == item.id}) {
items[index] = item.updateCompletion()
}
}
func saveItem() {
if let encodedData = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(encodedData, forKey: itemsKey)
}
}
}
'Swift > etc' 카테고리의 다른 글
[Xcode] 디버거에서 data 타입을 사람이 볼 수 있는 방식으로 변환하는 법 (0) | 2023.03.18 |
---|---|
[UIKit] init(frame:)과 init(coder:)은 어떤 차이가 있는가? (0) | 2023.03.16 |
[Swift] Type of expression is ambiguous... 에러 (0) | 2023.03.15 |
[Swift] self와 Self의 차이점 (0) | 2023.03.11 |
[Swift] 이중 배열과 관련된 "Fatal error: Index out of range" 문제 (0) | 2022.07.10 |