Skip to content

Commit

Permalink
refactor: CoreDataManager 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
maxhyunm committed Sep 17, 2023
1 parent cca8169 commit 28846e1
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 48 deletions.
3 changes: 0 additions & 3 deletions Diary/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import CoreData

@main
class AppDelegate: UIResponder, UIApplicationDelegate {



func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
Expand Down
5 changes: 3 additions & 2 deletions Diary/App/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

let coreDataManager = CoreDataManager(entityName: "Diary")

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }

window = UIWindow(windowScene: windowScene)
let diaryListViewController = DiaryListViewController()
diaryListViewController.coreDataManager = coreDataManager
let navigationController = UINavigationController(rootViewController: diaryListViewController)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
Expand Down Expand Up @@ -50,7 +51,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

// Save changes in the application's managed object context when the application transitions to the background.
do {
try CoreDataManager.shared.saveContext()
try coreDataManager.saveContext()
} catch {
fatalError(CoreDataError.saveFailure.message)
}
Expand Down
15 changes: 9 additions & 6 deletions Diary/Controller/DiaryDetailViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ final class DiaryDetailViewController: UIViewController, ShareDisplayable {
return textView
}()

private let container = CoreDataManager.shared.persistentContainer
private let coreDataManager: CoreDataManager
private var diary: Diary
private var isNew: Bool
private var latitude: Double?
private var longitude: Double?

init(latitude: Double?, longitude: Double?) {
self.diary = CoreDataManager.shared.createDiary()
init(latitude: Double?, longitude: Double?, coreDataManager: CoreDataManager) {
self.coreDataManager = coreDataManager
self.diary = coreDataManager.createDiary()
self.isNew = true
self.latitude = latitude
self.longitude = longitude
Expand All @@ -32,9 +33,11 @@ final class DiaryDetailViewController: UIViewController, ShareDisplayable {
fetchWeather()
}

init(_ diary: Diary) {
init(_ diary: Diary, coreDataManager: CoreDataManager) {
self.coreDataManager = coreDataManager
self.diary = diary
self.isNew = false

super.init(nibName: nil, bundle: nil)
}

Expand Down Expand Up @@ -134,7 +137,7 @@ final class DiaryDetailViewController: UIViewController, ShareDisplayable {
alertBuilder.addAction(.delete) { [weak self] _ in
guard let self else { return }
do {
try CoreDataManager.shared.deleteDiary(self.diary)
try coreDataManager.deleteEntity(self.diary)
self.navigationController?.popViewController(animated: true)
} catch CoreDataError.deleteFailure {
let additionalAlertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert)
Expand Down Expand Up @@ -191,7 +194,7 @@ extension DiaryDetailViewController: UITextViewDelegate {
guard !contents.isEmpty else { return }

do {
try CoreDataManager.shared.saveContext()
try coreDataManager.saveContext()
} catch CoreDataError.saveFailure {
let alertBulder = AlertBuilder(viewController: self, prefferedStyle: .alert)
alertBulder.setType(.coreDataError(error: .saveFailure))
Expand Down
34 changes: 27 additions & 7 deletions Diary/Controller/DiaryListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class DiaryListViewController: UIViewController {
return formatter
}()

private let container = CoreDataManager.shared.persistentContainer
var coreDataManager: CoreDataManager?
private var diaryList = [Diary]()

private var latitude: Double?
Expand Down Expand Up @@ -62,8 +62,10 @@ final class DiaryListViewController: UIViewController {

private func setupNavigationBarButton() {
let addDiary = UIAction(image: UIImage(systemName: "plus")) { [weak self] _ in
guard let self else { return }
let createDiaryView = DiaryDetailViewController(latitude: self.latitude, longitude: self.longitude)
guard let self, let coreDataManager else { return }
let createDiaryView = DiaryDetailViewController(latitude: self.latitude,
longitude: self.longitude,
coreDataManager: coreDataManager)
self.navigationController?.pushViewController(createDiaryView, animated: true)
}

Expand All @@ -77,8 +79,13 @@ final class DiaryListViewController: UIViewController {
}

private func readCoreData() {
guard let coreDataManager else { return }

do {
let fetchedDiaries = try CoreDataManager.shared.fetchDiary()
guard let fetchedDiaries = try coreDataManager.fetchEntity(sortBy: "createdAt") as? [Diary] else {
throw CoreDataError.unknown
}

diaryList = fetchedDiaries.filter { $0.title != nil }
tableView.reloadData()
} catch CoreDataError.dataNotFound {
Expand Down Expand Up @@ -129,17 +136,22 @@ extension DiaryListViewController: UITableViewDelegate, ShareDisplayable {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let diaryToEdit = diaryList[indexPath.row]
let createVC = DiaryDetailViewController(diaryToEdit)

guard let coreDataManager else { return }

let createVC = DiaryDetailViewController(diaryToEdit, coreDataManager: coreDataManager)

navigationController?.pushViewController(createVC, animated: true)
}

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) ->
UISwipeActionsConfiguration? {
guard let coreDataManager else { return nil }

let delete = UIContextualAction(style: .normal, title: "") { (_, _, success: @escaping (Bool) -> Void) in
let selectedDiary = self.diaryList[indexPath.row]
do {
try CoreDataManager.shared.deleteDiary(selectedDiary)
try coreDataManager.deleteEntity(selectedDiary)
self.readCoreData()
success(true)
} catch CoreDataError.deleteFailure {
Expand Down Expand Up @@ -196,9 +208,17 @@ extension DiaryListViewController: CLLocationManagerDelegate {

extension DiaryListViewController: UISearchBarDelegate {
func searchDiary(with keyword: String) {
guard let coreDataManager else { return }

if keyword.count > 0 {
do {
let fetchedDiaries = try CoreDataManager.shared.filterDiary(keyword)
let predicate = "title CONTAINS[cd] %@ OR body CONTAINS[cd] %@"
guard let fetchedDiaries = try coreDataManager.filterEntity(keyword,
predicate: predicate,
sortBy: "createdAt") as? [Diary] else {
throw CoreDataError.unknown
}

diaryList = fetchedDiaries.filter { $0.title != nil }
tableView.reloadData()
} catch CoreDataError.dataNotFound {
Expand Down
67 changes: 37 additions & 30 deletions Diary/Model/CoreData/CoreDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,50 @@
import CoreData

class CoreDataManager {
static let shared = CoreDataManager()
var persistentContainer: NSPersistentContainer

lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Diary")
container.loadPersistentStores(completionHandler: { (_, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()

private init() {}
init(entityName: String) {
persistentContainer = {
let container = NSPersistentContainer(name: entityName)
container.loadPersistentStores(completionHandler: { (_, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
}

func fetchDiary() throws -> [Diary] {
let request: NSFetchRequest<Diary> = Diary.fetchRequest()
let sortByDate = NSSortDescriptor(key: "createdAt", ascending: false)
request.sortDescriptors = [sortByDate]
func fetchEntity<T: NSManagedObject>(sortBy: String? = nil) throws -> [T] {
let request: NSFetchRequest<T> = NSFetchRequest(entityName: persistentContainer.name)

if let sortBy {
let sorted = NSSortDescriptor(key: sortBy, ascending: false)
request.sortDescriptors = [sorted]
}

do {
let diaries = try persistentContainer.viewContext.fetch(request)
return diaries
let entities: [T] = try persistentContainer.viewContext.fetch(request)
return entities
} catch {
throw CoreDataError.dataNotFound
}
}

func filterDiary(_ keyword: String) throws -> [Diary] {
let request: NSFetchRequest<Diary> = Diary.fetchRequest()
let predicate = NSPredicate(format: "title CONTAINS[cd] %@ OR body CONTAINS[cd] %@", keyword, keyword)
request.predicate = predicate
let sortByDate = NSSortDescriptor(key: "createdAt", ascending: false)
request.sortDescriptors = [sortByDate]
func filterEntity<T: NSManagedObject>(_ keyword: String, predicate: String, sortBy: String? = nil) throws -> [T] {
let request: NSFetchRequest<T> = NSFetchRequest(entityName: persistentContainer.name)

let predicated = NSPredicate(format: predicate, keyword, keyword)
request.predicate = predicated

if let sortBy {
let sorted = NSSortDescriptor(key: sortBy, ascending: false)
request.sortDescriptors = [sorted]
}

do {
let diaries = try persistentContainer.viewContext.fetch(request)
return diaries
let entities = try persistentContainer.viewContext.fetch(request)
return entities
} catch {
throw CoreDataError.dataNotFound
}
Expand All @@ -58,15 +65,15 @@ class CoreDataManager {
return newDiary
}

func deleteDiary(_ diary: Diary?) throws {
guard let diary = diary else {
func deleteEntity<T: NSManagedObject>(_ entity: T?) throws {
guard let entity else {
throw CoreDataError.deleteFailure
}
persistentContainer.viewContext.delete(diary)
persistentContainer.viewContext.delete(entity)
try saveContext()
}

func saveContext () throws {
func saveContext() throws {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
Expand Down

0 comments on commit 28846e1

Please sign in to comment.