-
[Swift] CoreData 사용해보기: CRUD 구현 가이드개발/Swift 2024. 5. 18. 13:50
문제
- API 네트워킹시 네트워크 문제가 있을경우 내부저장 데이터를 리턴해주는 로직 필요.
- CoreData는 내부데이터 이므로 Repository 에서 접근 하는게 맞다고 판단 했다.
근데 CoreData는 Appdelegate의 persistentContainer.viewContext 에 접근 해야함
Repository -> CoreData -> Appdelegate
이는 클린 아키텍쳐 구성상 의존성의 방향이 잘못되었다 생각
해결
- CoreData 를 사용해서 데이터를 저장 & 사용
- Repository 생성시 viewContext를 주입받아 사용
Coordinator 패턴이나 의존성 주입 하는 부분에서 해주면 좋을것 같다.
let appDelegate = UIApplication.shared.delegate as? AppDelegate let viewContext = appDelegate?.persistentContainer.viewContext let repository = NewsRepository(viewContext: viewContext, network: NewsNetwork()) let viewModel = ViewModel(repository: repository) let viewController = ViewController(viewModel: viewModel) let rootVC = UINavigationController(rootViewController: viewController)
구현
- CoreData Entity 설정은 이미 해둠
삭제
private func deleteAllNewsCoreData() { let fetchRequestResult: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "NewsItem") let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequestResult) do { try viewContext?.execute(deleteRequest) try viewContext?.save() } catch let error { print("deleteAllNewsCoreData Error - \\(error)") } }
NewsItem 엔티티 저장된 리스트 모두 지워버림
저장
private func saveNewsCoreData(news: [News]) { guard let viewContext = viewContext, let entity = NSEntityDescription.entity(forEntityName: "NewsItem", in: viewContext) else { return } news.forEach { newsItem in let newsObject = NSManagedObject(entity: entity, insertInto: viewContext) newsObject.setValue(newsItem.publishedAt, forKey: "publishedAt") newsObject.setValue(newsItem.title, forKey: "title") newsObject.setValue(newsItem.urlToImage, forKey: "urlToImage") newsObject.setValue(newsItem.url, forKey: "url") } do { try viewContext.save() } catch let error { print("saveNewsCoreData Error - \\(error)") } }
객체의 데이터를 모두 꺼내서 Coredata 엔티티 생성 후 (반복) 저장
읽기
private func readNewsCoreData() -> [News] { let fetchRequest: NSFetchRequest<NewsItem> = NewsItem.fetchRequest() do { guard let result = try viewContext?.fetch(fetchRequest) else { return [] } let news: [News] = result.compactMap { news in guard let title = news.value(forKey: "title") as? String, let url = news.value(forKey: "url") as? String else { return nil } let publishedAt = news.value(forKey: "publishedAt") as? Date let urlToImage = news.value(forKey: "urlToImage") as? String return News(title: title, url: url, urlToImage: urlToImage, publishedAt: publishedAt) } return news } catch let error { print("readNewsCoreData Error - \\(error)") return [] } }
Coredata 엔티티 (리스트) 꺼내와서 객체 생성후 리턴
'개발 > Swift' 카테고리의 다른 글
[Error] suspend resume partial function for XXX (0) 2024.08.20 [Error] navigationbar subview 레이아웃 에러 (0) 2024.08.20 [Swift] Tab bar 와 Page view를 동시에 사용할때 (0) 2024.05.18 iOS 앱 자동화 Fastlane Fastfile 작성 Cheatsheet (0) 2024.04.29 Swift 딥링크 처리- AppDelegate와 SceneDelegate (0) 2024.04.12