Ayaan🦖, zhilly🔥 이 만든 Core Data를 활용한 일기장 애플리케이션 입니다.
개발 기간 : 2022-12-19 ~ 2023-01-06
Ayaan | zhilly |
---|---|
- 22.12.20
- SwiftLint 적용
- DiaryTableView Type 구현
- DiaryCell Type 구현
- 22.12.21
- DiaryView Type 구현
- DiaryListViewController Type 구현
- DiaryViewController Type 구현
- Keyboard 관련 기능구현
- DiaryTextView의 PlaceHolder 기능구현
- 22.12.22
- 코드 리팩터링
- 매직 리터럴 제거
- 22.12.26
- CoreData에 DiaryData Entity 구현
- DiaryManageable Protocol 구현
- DiaryDataManager Type 구현
- Diary Type 재정의
- DiaryCoreDataStack Type 구현
- 22.12.27
- DiaryViewController 리팩토링
- 키보드관련 기능구현
- ObjectID를 활용하여 CoreData를 수정, 삭제할 수 있도록 구현
- 22.12.28
- Diary 상세 화면에 더보기 버튼 기능(공유, 삭제) 구현
- CoreData의 데이터를 관찰하는 NotificationCenter 구현
- Cell의 Swipe 기능 구현
- Activity View 기능 구현
- 코드 리팩터링
- 매직 리터럴 제거 및 네이밍 변경
- 23.01.02
- ManagedObjectModel protocol 구현
- DiaryExtractor 타입 구현 및 적용
- DiaryManageable를 CoreDataManageable로 변경 및 수정
- DiaryManager에 싱글톤 패턴 적용
- Alert Factory 메서드 구현 및 적용
- DiaryError Type 구현 및 적용
- 코드 리팩터링
- CRUD를 구현하기 위해서 CoreData의 Container를 이용해야했습니다.
AppDelegate
에 구현을 해두면 사용할 때마다AppDelegate
에서 가져오고 언래핑하고 할당해주는 번거로움이 있었습니다.- CoreData를 사용하기 위해 접근해야 되는 Container는
DiaryCoreDataStack
이라는 싱글톤 객체로 만들었고DiaryDataManager
객체를 통해 CRUD의 역할을 수행했습니다. DiaryCoreDataStack
의 Singleton 객체를DiaryDataManager
에서 사용하는 구조가 어색하게 느껴졌습니다.DiaryDataManager
에Core Data Container
를 가지도록 구현하여DiaryManager
타입을 구현했습니다.
- CoreData의 Object에서
UUID
를id
로 사용하여 관리할지 제공되는ObjectID
를 이용할지를 고민했습니다. UUID
를 사용하면 특정 object를 얻으려면fetch
작업을 따로 정의해서 사용해야 하는 단점이 있었습니다.objectID
를 사용하면 context의 메서드를 이용해서update
,delete
를 손쉽게 사용할 수 있기 때문에objectID
를 사용했습니다.
- CoreData로 사용하는 모델 하나로 구현을 해야할까, 아니면 앱에서 실질적으로 사용하는 모델 타입 하나를 추가로 만들어 두개의 모델로 구현을 해야할 까 고민했습니다.
- 한 개로 하면 CoreData 모델이 비즈니스 로직을 담당할 수는 있겠지만, CoreData 모델의 역할이 많아진다고 판단했습니다.
- 그렇다고
ViewController
에서 비즈니스 로직을 담당하는 것도 아키텍처 관점에서 어긋난다고 생각했습니다. - 따라서 실질적으로 사용하는 모델 타입을 만들어 비즈니스 로직을 처리하게 하여 이를 해결하였습니다.
- Core Data Entity를 추가해야 할 때, Entity를 관리하는 Manager 및 VC에서 사용할 Model의 추상화를 위해
objectID
프로퍼티를 소유하고,init?(from: NSManagedObject)
을 할 수 있는 추상화 객체를 프로토콜로 구현했습니다.
- 프로젝트를 구현하다 보니 같은 비슷한 Alert을 생성하는 코드가 많았습니다.
- 팩토리 패턴을 이용하면 반복되는 코드는 줄이고 편리하게 Alert을 보여줄 수 있다고 생각하여 구현하였습니다.
자세히 보기
- 지역 및 언어에 맞는 작성일자를 표현해주려고 했습니다. 하지만
Locale.current
의 값이 지역을 변경하고 언어를 변경해도eu_KR
과 같이 언어 부분이eu
로 표현되는 문제가 발생했습니다.
Locale.preferredLanguages.first
를 사용하여 설정된 언어 중 첫번째 언어에 해당하는 값으로 작성일자를 표현되게 해주어 문제를 해결했습니다.Locale.current
는 현재 App의 지원되는Localization
에 영향을 받는 것을 알게되었습니다. 어떤Localization
을 사용할지 결정해서Locale.current
에 따라서 UI를 다르게 표현해 줄 예정입니다.
자세히 보기
-
요구사항에 코드로만 UI를 작성하라는 문구가 있어서 시도해보았습니다.
- Main.storyboard 삭제
- info.plist에서 storyboard관련 삭제
- SceneDelegate에서 ViewController로 이동할 수 있도록 RootViewController 설정
-
이와 같이 진행하고 실행시에 Main스토리보드 관련하여 에러가 뜨는 것을 확인했습니다
-
위의 추가 과정을 통해 Main 스토리보드 없이 프로젝트를 진행할 수 있었습니다!
자세히 보기
- MainStoryboard가 없이 코드로만 UI를 구성해 봤습니다.
NavigationController
및rootViewController
를SceneDelegate
에서 인스턴스화 해주어서 첫 화면이 보여지게 구현해 봤습니다. 하지만 iOS 15부터 NavigationBar의 디자인이 수정되어 구분선이 보이지 않는 현상이 발생했습니다. UINavigationBarAppearance
를 인스턴스화 한 후configureWithOpaqueBackground()
메서드로 현재 테마에 적합한 불투명한 bar appearance object로 구성한 뒤NavigationController.navigationBar
에standardAppearance
및scrollEdgeAppearance
에 할당해 줌으로 이전에 발생한 문제를 해결했습니다.
코드 보기
let navigationController = UINavigationController(rootViewController: mainViewController)
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.configureWithOpaqueBackground()
navigationController.navigationBar.standardAppearance = navigationBarAppearance
navigationController.navigationBar.scrollEdgeAppearance = navigationBarAppearance
자세히 보기
// 1번
static let identifier: String = String(describing: self)
// 2번
static func getIdentifier() -> String {
return String(describing: self)
}
- 1번과 2번 방법 중 Cell의 identifier을 어떻게 사용하는 방법이 더 나은지 고민했습니다.
- 프로토콜을 사용해서 해결했습니다.
코드 보기
protocol ReusableView: class {
static var defaultReuseIdentifier: String { get }
}
extension ReusableView where Self: UIView {
static var defaultReuseIdentifier: String {
return String(describing: self)
}
}
- CoreData 모델 사용
- Factory Method Pattern 활용
- Singleton Pattern 적용
- UITableViewDiffableDataSource
- Date Formatter 활용
- UIContextualAction
- UISwipeActionsConfiguration
- UIActivityViewController