728x90
SMALL
가계부 앱에서 한 번 입력한 지출/수입 데이터를 삭제하는 기능은 반드시 필요합니다. 특히 사용자가 실수로 입력했거나, 잘못된 이미지를 포함한 경우 Core Data + 이미지 파일까지 함께 삭제하는 구조가 되어야 합니다.
이번 글에서는 deleteTransaction(id:) 함수를 중심으로 Core Data에서의 삭제 처리 흐름과 이미지 정리 방식까지 상세히 정리합니다.
🧩 1. 삭제 함수 코드
func deleteTransaction(id: UUID) -> AnyPublisher<Bool, Error> {
return Future { [weak self] promise in
guard let self = self else {
print("❌ deleteTransaction: self가 nil입니다.")
return
}
let fetchRequest: NSFetchRequest<ExpenseEntity> = ExpenseEntity.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "id == %@", id.uuidString)
do {
let result = try self.context.fetch(fetchRequest)
guard let entityToDelete = result.first else {
print("❌ deleteTransaction: 해당 ID에 해당하는 항목을 찾을 수 없음")
promise(.failure(NSError(domain: "TransactionNotFound", code: 404)))
return
}
// 이미지 경로가 있는 경우 파일도 삭제
if let imagePath = entityToDelete.imagePath {
let imageDeleted = self.storageManager.deleteFolder(for: imagePath)
if imageDeleted {
print("🗑️ 이미지 삭제 성공")
} else {
print("⚠️ 이미지 삭제 실패 (파일이 없을 수도 있음)")
}
}
self.context.delete(entityToDelete)
try self.context.save()
print("✅ deleteTransaction: Core Data 삭제 성공")
promise(.success(true))
} catch {
print("❌ deleteTransaction: 삭제 중 오류 발생 - \(error.localizedDescription)")
promise(.failure(error))
}
}
.eraseToAnyPublisher()
}
🧭 함수 흐름 설명: deleteTransaction(_:) 은 어떻게 작동하는가?
사용자가 특정 트랜잭션을 삭제 요청하면, 이 함수는 Core Data와 파일 시스템을 함께 정리합니다. 각 단계의 흐름은 아래와 같습니다.
🔍 1단계: 해당 ID의 엔티티 조회
fetchRequest.predicate = NSPredicate(format: "id == %@", id.uuidString)
- 무엇을 하는가?
전달받은 UUID로 일치하는 데이터를 Core Data에서 찾습니다. - 포인트
존재하지 않는다면 실패 처리하며, 이후 단계는 실행되지 않습니다.
🖼️ 2단계: 이미지 파일 삭제 (있다면)
if let imagePath = entityToDelete.imagePath {
let imageDeleted = self.storageManager.deleteFolder(for: imagePath)
}
- 무엇을 하는가?
이미지가 저장되어 있던 폴더(파일 경로)를 찾아 삭제합니다. - 왜 필요한가?
Core Data는 이미지 자체를 저장하지 않고 경로만 저장하므로, 직접 파일 시스템에서 삭제해야 공간이 낭비되지 않습니다.
🗑️ 3단계: Core Data에서 데이터 삭제
self.context.delete(entityToDelete)
- 무엇을 하는가?
찾은 ExpenseEntity 객체를 context에서 제거합니다.
💾 4단계: 저장 & 성공 반환
try self.context.save()
promise(.success(true))
- 무엇을 하는가?
변경 사항을 Core Data에 반영하고, 성공 결과를 Combine 구독자에게 전달합니다.
🔁 요약 플로우 차트
📍 사용자로부터 삭제할 UUID 전달
↓
1️⃣ Core Data에서 해당 ID의 엔티티 검색
↓
2️⃣ 이미지 경로가 있다면 → 파일 시스템에서 이미지 삭제
↓
3️⃣ Core Data에서 해당 엔티티 삭제
↓
4️⃣ context.save()로 저장 후 → 성공 반환
💡 정리 포인트
- 단순히 CoreData만 지우면 안 되고, 연관된 이미지 파일까지 반드시 삭제해야 실제 앱 용량 관리가 됩니다.
- 삭제 후에도 .sink(receiveValue:) 등을 통해 UI 상태를 갱신할 수 있도록 Combine 구조를 활용합니다.
- ID 기준 삭제는 안정적인 방식이며, 이 방식은 iCloud 연동이나 멀티 디바이스 앱에서도 유용하게 활용됩니다.
[함꼐 보면 좋은 글]
728x90
LIST
'Project > ReceiptMind' 카테고리의 다른 글
| 🧾 iOS MVVM 가계부 앱 - 거래 내역 조회(Read), 수정(Update), 삭제(Delete) 기능 완벽 구현 (1) | 2025.08.03 |
|---|---|
| 💸 iOS MVVM 가계부 앱 - ViewModel(TransactionViewModel) 구조 완벽 정리 (0) | 2025.08.03 |
| 📚 iOS MVVM 가계부 앱 - Core Data 수정(Update) + 이미지까지 깔끔히 반영하는 법 (1) | 2025.08.02 |
| 📚Core Data로 지출 내역 불러오기(Read) 정리 (0) | 2025.08.02 |
| 💾 Core Data와 FileManager로 지출 내역 저장하기 (2) | 2025.08.01 |