Skip to content

Commit

Permalink
refactlr: CoreDataError 타입 생성, 예외처리 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
maxhyunm committed Sep 10, 2023
1 parent 12150ec commit f864693
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 37 deletions.
5 changes: 1 addition & 4 deletions Diary+CoreDataClass.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
//
//

import Foundation
import CoreData

@objc(Diary)
public class Diary: NSManagedObject {

}
public class Diary: NSManagedObject {}
3 changes: 0 additions & 3 deletions Diary+CoreDataProperties.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
//
//

import Foundation
import CoreData

extension Diary {

@nonobjc public class func fetchRequest() -> NSFetchRequest<Diary> {
return NSFetchRequest<Diary>(entityName: "Diary")
}
Expand All @@ -19,7 +17,6 @@ extension Diary {
@NSManaged public var body: String?
@NSManaged public var createdAt: Date?
@NSManaged public var id: UUID?

}

extension Diary: Identifiable {}
12 changes: 8 additions & 4 deletions Diary.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
BA1A55EB2A9D84AF0012C89D /* DiaryEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA1A55EA2A9D84AF0012C89D /* DiaryEntity.swift */; };
BA1A55ED2A9D90810012C89D /* DateFormatter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA1A55EC2A9D90810012C89D /* DateFormatter+.swift */; };
BABBDAE52A9F13A200D8D50B /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BABBDAE42A9F13A200D8D50B /* DecodingError.swift */; };
BABBDB342AA6D05A00D8D50B /* ShareDiary.swift in Sources */ = {isa = PBXBuildFile; fileRef = BABBDB332AA6D05A00D8D50B /* ShareDiary.swift */; };
BABBDB342AA6D05A00D8D50B /* ShareDisplayable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BABBDB332AA6D05A00D8D50B /* ShareDisplayable.swift */; };
BABBDB362AAD904100D8D50B /* CoreDataError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BABBDB352AAD904100D8D50B /* CoreDataError.swift */; };
C739AE25284DF28600741E8F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE24284DF28600741E8F /* AppDelegate.swift */; };
C739AE27284DF28600741E8F /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE26284DF28600741E8F /* SceneDelegate.swift */; };
C739AE29284DF28600741E8F /* DiaryListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE28284DF28600741E8F /* DiaryListViewController.swift */; };
Expand All @@ -41,7 +42,8 @@
BA1A55EA2A9D84AF0012C89D /* DiaryEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryEntity.swift; sourceTree = "<group>"; };
BA1A55EC2A9D90810012C89D /* DateFormatter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+.swift"; sourceTree = "<group>"; };
BABBDAE42A9F13A200D8D50B /* DecodingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodingError.swift; sourceTree = "<group>"; };
BABBDB332AA6D05A00D8D50B /* ShareDiary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareDiary.swift; sourceTree = "<group>"; };
BABBDB332AA6D05A00D8D50B /* ShareDisplayable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareDisplayable.swift; sourceTree = "<group>"; };
BABBDB352AAD904100D8D50B /* CoreDataError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataError.swift; sourceTree = "<group>"; };
C739AE21284DF28600741E8F /* Diary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Diary.app; sourceTree = BUILT_PRODUCTS_DIR; };
C739AE24284DF28600741E8F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C739AE26284DF28600741E8F /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -87,7 +89,7 @@
isa = PBXGroup;
children = (
636B19AB2AA6C5E900B5242D /* AlertDisplayble.swift */,
BABBDB332AA6D05A00D8D50B /* ShareDiary.swift */,
BABBDB332AA6D05A00D8D50B /* ShareDisplayable.swift */,
);
path = Protocol;
sourceTree = "<group>";
Expand Down Expand Up @@ -150,6 +152,7 @@
isa = PBXGroup;
children = (
BABBDAE42A9F13A200D8D50B /* DecodingError.swift */,
BABBDB352AAD904100D8D50B /* CoreDataError.swift */,
);
path = Error;
sourceTree = "<group>";
Expand Down Expand Up @@ -318,7 +321,8 @@
63BB62B52AA182AA00524DCB /* CoreDataManager.swift in Sources */,
63E527392A9D97160000FBA6 /* CreateDiaryViewController.swift in Sources */,
BABBDAE52A9F13A200D8D50B /* DecodingError.swift in Sources */,
BABBDB342AA6D05A00D8D50B /* ShareDiary.swift in Sources */,
BABBDB362AAD904100D8D50B /* CoreDataError.swift in Sources */,
BABBDB342AA6D05A00D8D50B /* ShareDisplayable.swift in Sources */,
63BB62B32AA181BE00524DCB /* Diary+CoreDataProperties.swift in Sources */,
BA1A55EB2A9D84AF0012C89D /* DiaryEntity.swift in Sources */,
63BB62B22AA181BE00524DCB /* Diary+CoreDataClass.swift in Sources */,
Expand Down
6 changes: 5 additions & 1 deletion Diary/App/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// to restore the scene back to its current state.

// Save changes in the application's managed object context when the application transitions to the background.
CoreDataManager.shared.saveContext()
do {
try CoreDataManager.shared.saveContext()
} catch {
fatalError(CoreDataError.saveFailure.message)
}
}


Expand Down
33 changes: 28 additions & 5 deletions Diary/Controller/CreateDiaryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import UIKit

final class CreateDiaryViewController: UIViewController, AlertDisplayable, ShareDiary {
final class CreateDiaryViewController: UIViewController, AlertDisplayable, ShareDisplayable {
private let textView: UITextView = {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
Expand Down Expand Up @@ -94,8 +94,20 @@ final class CreateDiaryViewController: UIViewController, AlertDisplayable, Share
let cancelAction = UIAlertAction(title: "취소", style: .cancel)
let deleteAction = UIAlertAction(title: "삭제", style: .destructive) { [weak self] _ in
guard let self else { return }
CoreDataManager.shared.deleteDiary(self.diary)
self.navigationController?.popViewController(animated: true)
do {
try CoreDataManager.shared.deleteDiary(self.diary)
self.navigationController?.popViewController(animated: true)
} catch CoreDataError.deleteFailure {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
self.showAlert(title: CoreDataError.deleteFailure.alertTitle,
message: CoreDataError.deleteFailure.message,
actions: [cancelAction])
} catch {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
self.showAlert(title: CoreDataError.deleteFailure.alertTitle,
message: CoreDataError.unknown.message,
actions: [cancelAction])
}
}

showAlert(title: "진짜요?", message: "정말로 삭제하시겠어요?", actions: [cancelAction, deleteAction])
Expand Down Expand Up @@ -141,13 +153,24 @@ extension CreateDiaryViewController {
}
}

// MARK: - UITextViewDelegate
extension CreateDiaryViewController: UITextViewDelegate {
func textViewDidEndEditing(_ textView: UITextView) {
let contents = textView.text.split(separator: "\n")
guard !contents.isEmpty else { return }

CoreDataManager.shared.saveContext()
do {
try CoreDataManager.shared.saveContext()
} catch CoreDataError.saveFailure {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
self.showAlert(title: CoreDataError.saveFailure.alertTitle,
message: CoreDataError.saveFailure.message,
actions: [cancelAction])
} catch {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
self.showAlert(title: CoreDataError.saveFailure.alertTitle,
message: CoreDataError.unknown.message,
actions: [cancelAction])
}
}

func textViewDidChange(_ textView: UITextView) {
Expand Down
30 changes: 24 additions & 6 deletions Diary/Controller/DiaryListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,16 @@ extension DiaryListViewController: AlertDisplayable {
let fetchedDiaries = try CoreDataManager.shared.fetchDiary()
diaryList = fetchedDiaries.filter { $0.title != nil }
tableView.reloadData()
} catch CoreDataError.dataNotFound {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
showAlert(title: CoreDataError.dataNotFound.alertTitle,
message: CoreDataError.dataNotFound.message,
actions: [cancelAction])
} catch {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
showAlert(title: "로드 실패", message: "데이터를 불러오지 못했습니다.", actions: [cancelAction])
showAlert(title: CoreDataError.dataNotFound.alertTitle,
message: CoreDataError.unknown.message,
actions: [cancelAction])
}
}
}
Expand Down Expand Up @@ -100,7 +107,7 @@ extension DiaryListViewController: UITableViewDataSource {
}
}

extension DiaryListViewController: UITableViewDelegate, ShareDiary {
extension DiaryListViewController: UITableViewDelegate, ShareDisplayable {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let diaryToEdit = diaryList[indexPath.row]
Expand All @@ -113,10 +120,21 @@ extension DiaryListViewController: UITableViewDelegate, ShareDiary {
UISwipeActionsConfiguration? {
let delete = UIContextualAction(style: .normal, title: "") { (_, _, success: @escaping (Bool) -> Void) in
let selectedDiary = self.diaryList[indexPath.row]

CoreDataManager.shared.deleteDiary(selectedDiary)
self.readCoreData()
success(true)
do {
try CoreDataManager.shared.deleteDiary(selectedDiary)
self.readCoreData()
success(true)
} catch CoreDataError.deleteFailure {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
self.showAlert(title: CoreDataError.deleteFailure.alertTitle,
message: CoreDataError.deleteFailure.message,
actions: [cancelAction])
} catch {
let cancelAction = UIAlertAction(title: "확인", style: .cancel)
self.showAlert(title: CoreDataError.deleteFailure.alertTitle,
message: CoreDataError.unknown.message,
actions: [cancelAction])
}
}

let share = UIContextualAction(style: .normal, title: "") { (_, _, success: @escaping (Bool) -> Void) in
Expand Down
24 changes: 13 additions & 11 deletions Diary/DataManager/CoreDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ class CoreDataManager {
let sortByDate = NSSortDescriptor(key: "createdAt", ascending: false)
request.sortDescriptors = [sortByDate]

let diaries = try persistentContainer.viewContext.fetch(request)
return diaries
do {
let diaries = try persistentContainer.viewContext.fetch(request)
return diaries
} catch {
throw CoreDataError.dataNotFound
}
}

func createDiary() -> Diary {
Expand All @@ -28,14 +32,14 @@ class CoreDataManager {
return newDiary
}

func deleteDiary(_ diary: Diary?) {
if let diary = diary {
persistentContainer.viewContext.delete(diary)
saveContext()
func deleteDiary(_ diary: Diary?) throws {
guard let diary = diary else {
throw CoreDataError.deleteFailure
}
persistentContainer.viewContext.delete(diary)
try saveContext()
}

// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Diary")
container.loadPersistentStores(completionHandler: { (_, error) in
Expand All @@ -46,15 +50,13 @@ class CoreDataManager {
return container
}()

// MARK: - Core Data Saving support
func saveContext () {
func saveContext () throws {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
throw CoreDataError.saveFailure
}
}
}
Expand Down
39 changes: 39 additions & 0 deletions Diary/Error/CoreDataError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// CoreDataError.swift
// Diary
//
// Created by Max, Hemg on 2023/09/10.
//

enum CoreDataError: Error {
case dataNotFound
case saveFailure
case deleteFailure
case unknown

var alertTitle: String {
switch self {
case .dataNotFound:
return "로드 실패"
case .saveFailure:
return "저장 실패"
case .deleteFailure:
return "삭제 실패"
case .unknown:
return "오류"
}
}

var message: String {
switch self {
case .dataNotFound:
return "데이터를 찾지 못했습니다."
case .saveFailure:
return "저장에 실패하였습니다."
case .deleteFailure:
return "삭제에 실패하였습니다."
case .unknown:
return "알 수 없는 오류입니다."
}
}
}
2 changes: 1 addition & 1 deletion Diary/Error/DecodingError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Error.swift
// Diary
//
// Created by Min Hyun on 2023/08/30.
// Created by Max, Hemg on 2023/08/30.
//

enum DecodingError: Error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

import UIKit

protocol ShareDiary {
protocol ShareDisplayable {
func shareDiary(_ diary: Diary?)
}

extension ShareDiary where Self: UIViewController {
extension ShareDisplayable where Self: UIViewController {
func shareDiary(_ diary: Diary?) {
guard let diary,
let title = diary.title,
Expand Down

0 comments on commit f864693

Please sign in to comment.