---
# System prepended metadata

title: PR

---

# PR

안녕하세요, 하비(@havilog)🙇🏻‍♂️🙇🏻! [Ayaan🦖](https://github.com/oneStar92), [zhilly🔥](https://github.com/zhilly11)입니다!
이번 스텝도 잘 부탁드립니다!!😁
Coredata 어렵네요...😭

# 📍고민했던 부분 

## ObjectID 사용
- CoreData의 Object에서 UUID를 id로 사용하여 관리할지 제공되는 ObjectID를 이용할지를 고민했습니다.
- UUID를 사용하면 특정 object를 얻으려면 fetch작업을 따로 정의해서 사용해야 하는 단점이 있었습니다.
- objectID를 사용하면 context의 메서드를 이용해서 update, delete를 손쉽게 사용할 수 있기 때문에 objectID를 사용했습니다.

## CoreDataStack 구현
- CRUD를 구현하기 위해서 CoreData의 Container를 이용해야했습니다.
- AppDelegate에 구현을 해두면 사용할 때마다 AppDelegate에서 가져오고 언래핑하고 할당해주는 번거로움이 있었습니다.
- 따라서 CRUD의 역할을 해주는 CoreDataStack 이라는 싱글톤 객체로 만들어서 사용했습니다.

## 모델
- CoreData로 사용하는 모델 하나로 구현을 해야할까, 아니면 앱에서 실질적으로 사용하는 모델 타입 하나를 추가로 만들어 두개의 모델로 구현을 해야할 까 고민했습니다.
- 한 개로 하면 CoreData 모델이 비즈니스 로직을 담당할 수는 있겠지만, CoreData 모델의 역할이 많아진다고 판단했습니다.
- 그렇다고 ViewController에서 비즈니스 로직을 담당하는 것도 아키텍처 관점에서 어긋난다고 생각했습니다.
- 따라서 실질적으로 사용하는 모델 타입을 만들어 비즈니스 로직을 처리하게 하여 이를 해결하였습니다.

<br>

# 📍해결하지 못한 부분

## **TemploryID(미해결)**
- NSFetchedResultsController를 이용하여 CoreData가 수정될때마다 자동으로 Diary List가 갱신되도록 구현했습니다.
- NSFetchedResultsController에서 받아오는 Snapshot은 TemploryID값이 포함되어 전달되는 문제가 발생했습니다.
- (TemploryID가 생성되는 이유는 아직 저장되지 않은 경우 개체 ID는 개체가 저장될 때 변경되는 임시 값입니다. [참고](https://developer.apple.com/documentation/coredata/nsmanagedobject/1506848-objectid))
- 처음 생성된 임시 objectID
`<x-coredata:///Task/tE1C5A230-A419-42D5-AF78-3327A09D13BD2>`
- 앱을 종료후 실행시킨 뒤 objectID
`<x-coredata://D6703834-ECB4-487B-84F8-330A215E16B7/Task/p13>`
- 해당 문제를 해결하는 방법을 찾지 못해서 NSFetchedResultsController를 사용하지 않고 Diary List를 갱신하도록 구현했습니다.
- havi는 혹시 이 현상을 해결하는 방법을 알고 계신가요???

<br>

# 📍조언을 얻고 싶은 부분

- DiaryCell을 모두 지운 후 +버튼을 클릭하게 되면 아래와 같은 AutoLayout 오류가 발생합니다.
- `UIStackView:0x136f23080.bottom == UITableViewCellContentView:0x136f23450.bottom - 8`로 발생되는 문제로는 파악했으나 어떻게 해결해야 되는지 감이 잡히지 않습니다... 도와주세요 havi🙇🏻‍♂️
![](https://i.imgur.com/6htmjuB.gif)

```bash
2022-12-28 21:46:34.502911+0900 Diary[92290:4407591] [LayoutConstraints] Unable to simultaneously satisfy constraints.
	Probably at least one of the constraints in the following list is one you don't want. 
	Try this: 
		(1) look at each constraint and try to figure out which you don't expect; 
		(2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x6000000dc5f0 V:|-(8)-[UIStackView:0x136f23080]   (active, names: '|':UITableViewCellContentView:0x136f23450 )>",
    "<NSLayoutConstraint:0x6000000dc640 UIStackView:0x136f23080.bottom == UITableViewCellContentView:0x136f23450.bottom - 8   (active)>",
    "<NSLayoutConstraint:0x6000000a3e80 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x136f23450.height == 0   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000000dc640 UIStackView:0x136f23080.bottom == UITableViewCellContentView:0x136f23450.bottom - 8   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
```

추가적으로 조언을 얻고 싶은 부분은 코멘트로 남겨놓았습니다!!


---


# PR

안녕하세요, 하비(@havilog)🙇🏻‍♂️🙇🏻! [Ayaan🦖](https://github.com/oneStar92), [zhilly🔥](https://github.com/zhilly11)입니다!
중간 중간 뜻밖에 오류들을 만나서 조금 해멨습니다 🥲
많이 알려주시면 열심히 배우겠습니다 ✏️ 3주간 리뷰 잘 부탁드립니다!


# 📍고민했던 부분 

## MainStoryboard없이 Code로 구현
- 요구사항에 코드로만 UI를 작성하라는 문구가 있어서 시도해보았습니다.
    1. Main.storyboard 삭제
    2. info.plist에서 storyboard관련 삭제
    3. SceneDelegate에서 ViewController로 이동할 수 있도록 RootViewController 설정

- 이와 같이 진행하고 실행시에 Main스토리보드 관련하여 에러가 뜨는 것을 확인했습니다
    1. 프로젝트 설정에서 Info탭에서 추가로 StoryBoard관련해서 삭제
    2. Build Settings에서 main storyboard관련 삭제 ![](https://i.imgur.com/6IpdAis.png)

- 위의 추가 과정을 통해 Main 스토리보드 없이 프로젝트를 진행할 수 있었습니다!

## NavigationBar 구분선
- MainStoryboard가 없이 코드로만 UI를 구성해 봤습니다. `NavigationController`및 `rootViewController`를 `SceneDelegate`에서 인스턴스화 해주어서 첫 화면이 보여지게 구현해 봤습니다. 하지만 iOS 15부터 NavigationBar의 디자인이 수정되어 구분선이 보이지 않는 현상이 발생했습니다.
- `UINavigationBarAppearance`를 인스턴스화 한 후 `configureWithOpaqueBackground()`메서드로 현재 테마에 적합한 불투명한 bar appearance object로 구성한 뒤 `NavigationController.navigationBar`에 `standardAppearance`및 `scrollEdgeAppearance`에 할당해 줌으로 이전에 발생한 문제를 해결했습니다.


## UITableDataSource
- `TableView`의 `DataSource`로 `UITableViewDiffableDataSource`를 사용했습니다. `UITableViewDiffableDataSource`의 경우 `ItemIdentifier`가 `Hashable`해야했으며 `ItemIdentifier`에 해당하는 `Diary` Type은 `Hashable`하지 못하는 문제가 발생했습니다.
- `Diary` Type이 인스턴스화 될 때 프로퍼티로 `UUID`를 할당해 줌으로 해당 문제를 해결했습니다.
- `Diary` Type이 `UUID`를 프로퍼티로 가지고 있는 것이 좋은 방향성인지 많은 고민을 했으나 추후 `CoreData`에서 검색등의 작업을 할때도 이러한 프로퍼티가 있으면 좋을 것 같다고 판단했습니다.


## Locale
- 지역 및 언어에 맞는 작성일자를 표현해주려고 했습니다. 하지만 `Locale.current`의 값이 지역을 변경하고 언어를 변경해도 `eu_KR`과 같이 언어 부분이 `eu`로 표현되는 문제가 발생했습니다.
- `Locale.preferredLanguages.first`를 사용하여 설정된 언어 중 첫번째 언어에 해당하는 값으로 작성일자를 표현되게 해주어 문제를 해결했습니다.

## DiaryView 재사용 고민
-  Diary 수정화면과 작성화면을 구현하는 과정에서 ViewController를 2개로 구현해야할까 라는 고민을 했었습니다.
- 고민해본 결과 2개의 ViewController보다는 1개에서 처리를 해서 재사용을 하자라는 방식으로 진행했습니다.

# 📍조언을 얻고 싶은 부분

조언을 얻고 싶은 부분은 코멘트로 남겨놓았습니다!!


![](https://i.imgur.com/KDKMb8l.png)
![](https://i.imgur.com/vW4CMqj.png)


navigationbar 구분선 문제
iOS15 부터 스타일이 바뀜

standardApperence
scroll~Apperence 는 같은 값이어야 한다?



둘 중에 뭐가 좋을까
static let identifier: String = String(describing: self)
    
static func getIdentifier() -> String {
        return String(describing: self)
}

## ------ PR ------