# ๐ ์ผ๊ธฐ์ฅ
<br>
## ๐พ ํ๋ก์ ํธ ์๊ฐ
>**ํ๋ก์ ํธ ๊ธฐ๊ฐ** : 2022-08-16 ~ 2022-09-02<br>
**์๊ฐ** : ๊ทธ๋ ๊ฒช์ ์ผ์ด๋ ์๊ฐ์ด๋ ๋๋์ ์ ๋ ์ผ๊ธฐ์ฅ ์ฑ์
๋๋ค. <br>
**๋ฆฌ๋ทฐ์ด** : [**์ ์ดํฌ**](https://github.com/jryoun1)
<br>
## ๋ชฉ์ฐจ
* [ํ์](#-ํ์)
* [์คํ ํ๋ฉด](#-์คํ-ํ๋ฉด)
* [๊ฐ๋ฐ ํ๊ฒฝ](#-๊ฐ๋ฐ-ํ๊ฒฝ)
* [ํต์ฌ ๊ฒฝํ](#-ํต์ฌ-๊ฒฝํ)
* [ํ์ ๋ผ์ธ](#-ํ์-๋ผ์ธ)
* [week2](#week-2)
* [week3](#week-3)
* [ํด๋ ๊ตฌ์กฐ](#-ํด๋-๊ตฌ์กฐ)
* [๊ตฌํ ๋ด์ฉ](#-๊ตฌํ-๋ด์ฉ)
* [ํธ๋ฌ๋ธ ์ํ
](#-ํธ๋ฌ๋ธ-์ํ
)
* [์ฐธ๊ณ ๋ฌธ์](#-์ฐธ๊ณ -๋ฌธ์)
<br>
## ๐ฅ ํ์
| [ํ์ด](https://github.com/seohyeon2) | [์ํค](https://github.com/yeeton37) |
|:---:|:---:|
|<img src = "https://i.imgur.com/0UjNUFH.jpg" width="200" height="230">|<img src = "https://i.imgur.com/TI2ExtK.jpg" width=200 height = 230>|
<br>
## ๐บ ์คํ ํ๋ฉด
| ๋ฉ์ธ ํ๋ฉด | ์ผ๋ฟ ํ๋ฉด |
|:---:|:---:|
|<img src = "https://i.imgur.com/XQ0vRmR.gif" width=200 height=400>|<img src = "https://i.imgur.com/9WikuB9.png" width=200 height=400>|
| ์ผ๊ธฐ์ฅ ์ถ๊ฐ ํ๋ฉด | ์ผ๊ธฐ์ฅ ์์ ํ๋ฉด |
|<img src = "https://i.imgur.com/dyWwzfX.gif" width=200 height=400>|<img src = "https://i.imgur.com/3plNOYs.gif" width=200 height=400>|
| ์ผ๊ธฐ์ฅ ๊ณต์ ํ๋ฉด | ์ผ๊ธฐ์ฅ ์ญ์ ํ๋ฉด |
|<img src = "https://i.imgur.com/11Cxkam.gif" width=200 height=400>|<img src = "https://i.imgur.com/ziIy5or.gif" width=200 height=400>|
<br>
## ๐ ๊ฐ๋ฐ ํ๊ฒฝ
[]()
[]()
[]()
<br>
## ๐ป ํต์ฌ ๊ฒฝํ
- [x] ์ฝ์ด๋ฐ์ดํฐ ๋ชจ๋ธ ์์ฑ
- [x] ํ
์ด๋ธ๋ทฐ์์ ์ค์์ดํ๋ฅผ ํตํ ์ญ์ ๊ธฐ๋ฅ ๊ตฌํ
- [x] CoreData๊ด๋ จ ๋ฉ์๋ ํ๋ ์์ํฌํ
- [x] DiffableDataSource์ process
- [x] UX๋ฅผ ๊ณ ๋ คํ ์ฝ๋ ์์ฑ
<br>
## ๐ ํ์ ๋ผ์ธ
### Week 2
- **2022-08-22 (์)**
- ๋ฐ์ดํฐ ์ ๋ฌ ๋ฐฉ์ ํ๋กํ ์ฝ์ ์ด์ฉํ ๋ฐฉ์์ผ๋ก ์์ ๋ฐ ๊ฐ์ธ ๊ณต๋ถ
- **2022-08-23 (ํ)**
- ์ผ๊ธฐ์ฅ STEP 2-1: CoreData Entity ์์ฑ
- **2022-08-24 (์)**
- ์ผ๊ธฐ์ฅ STEP 2-1: CoreData Create์ Delete ๊ตฌํ
- **2022-08-25 (๋ชฉ)**
- ์ผ๊ธฐ์ฅ STEP 2-2: CoreData Update ๊ตฌํ ๋ฐ ์ผ๊ธฐ์ฅ ์๋ ์ ์ฅ ๊ตฌํ
- **2022-08-26 (๊ธ)**
- ์ผ๊ธฐ์ฅ STEP 2-2: Error ๊ตฌํ ๋ฐ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ง์
์ ์๋์ ์ฅ ๋๋ ๊ธฐ๋ฅ ๊ตฌํ
### Week 3
- **2022-08-29 (์)**
- CoreData ๊ด๋ จ ๋ฉ์๋ ํ๋ ์์ํฌํ ๊ณต๋ถ
- **2022-08-30 (ํ)**
- CoreData ๊ด๋ จ ๋ฉ์๋ ํ๋ ์์ํฌํ ๊ณต๋ถ
- **2022-08-31 (์)**
- diffableDataSource ์ด์ ํด๊ฒฐ
- **2022-09-01 (๋ชฉ)**
- ์ผ๊ธฐ์ฅ ์ ์ฅ ์, ์คํจํ๋ ์ผ์ด์ค ์ฒ๋ฆฌ
- **2022-09-02 (๊ธ)**
- ํผ๋๋ฐฑ ๋ฐํ์ผ๋ก ์ ๋ฐ์ ์ธ ์ฝ๋ ์์
<br>
## ๐ ํด๋ ๊ตฌ์กฐ
```swift
.
โโโ Diary/
โโโ Diary
โโโ info.plist
โโโ Resources/
โ โโโ LaunchScreen
โ โโโ Assets
โโโ Sources/
โโโ AppDelegate
โโโ SceneDelegate
โโโ Util/
โ โโโ Common/
โ โ โโโ Enum/
โ โ โโโ Section
โ โ โโโ Extension/
โ โ โโโ UIViewController + extension
โ โ โโโ Error/
โ โ โโโ CoreDataError
โ โ โโโ Protocol/
โ โ โโโ ReuseIdentifying
โ โ โโโ SendDataDelegate
โ โ โโโ CoreDataProcessing
โ โโโ JSONData
โโโ Controllers/
โ โโโ DiaryDetailViewController
โ โโโ DiaryListTableViewController
โโโ Views/
โ โโโ DiaryTableViewCell
โโโ Models/
โโโ DiaryContents + CoreDataClass
โโโ DiaryContents + CoreDataProperties
โโโ DiarySample
โโโ DataManager
```
<br>
## ๐ง ๊ตฌํ ๋ด์ฉ
|๊ตฌํ ์์น(ํ์ผ๋ช
)|ํต์ฌ ๊ตฌํ ๋ด์ฉ|
|:--|:--|
|`CoreDataError`|`CoreData` ๊ด๋ จ ์๋ฌ ํ์
๊ตฌํ|
|`ReuseIdentifying`|`Identifier` ๋ค์์คํ์ด์ค ์ฒ๋ฆฌ๋ฅผ ์ํ ํ๋กํ ์ฝ ๊ตฌํ|
|`SendDataDelegate`| ๋ทฐ์ปจํธ๋กค๋ฌ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌํด์ฃผ๋ ํ๋กํ ์ฝ ๊ตฌํ|
|`CoreDataProcessing`| `CoreData` ๊ด๋ จ ๋ฉ์๋ ๊ตฌํ|
|`DiaryDetailViewController`|์ผ๊ธฐ ์์ฑ ๋ฐ ์
๋ฐ์ดํธ ๊ธฐ๋ฅ, ์กํฐ๋นํฐ๋ทฐ, ์๋ฆผ์ฐฝ ๊ตฌํ|
|`DiaryListTableViewController`|์ค์์ดํ ์ ์ผ๊ธฐ ์ญ์ ๋๋ ๊ธฐ๋ฅ ๊ตฌํ|
|`SceneDelegate`|๋ฐฑ๊ทธ๋ผ์ด ์ง์
์ ์๋ ์ ์ฅ๋๋ ๊ธฐ๋ฅ ๊ตฌํ|
|`Diary`|`DiaryContents` Entities ๊ตฌํ|
|`DataManager`|`DiffableDataSource`์ `DiffableDataSourceSnapshot`์ ๊ฐ์ง๊ณ ์๋ ์ฑ๊ธํค ๊ตฌํ|
|`Section`|`DiffableDataSource`์์ ์ฌ์ฉํ ์น์
์ด๊ฒจํ ์ ์|
<br>
## ๐ ํธ๋ฌ๋ธ ์ํ
### 1. DiffableDataSource์ dequeueReusableCell ํธ์ถ ์ด์
- ๋ฌธ์ ์ํฉ
- cell์ ๋ณด์ฌ์ง๋ ๋ฐ์ดํฐ๊ฐ ์์ ๋ ๋๋ง๋ค, `dequeueReusableCell` ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ์ง๋ง cell์ ๋ฐ์๋์ต๋๋ค.
- ์ด ๋๋ฌธ์ `dequeueReusableCell`๋ฉ์๋๋ฅผ `viewDidLoad` ๊ฐ ์๋ `viewWillAppear`๋ `viewDidAppear` ์ ์์น์์ผ ํ๋ฉด์ด ๋ค์ ๋ํ๋ ๋๋ง๋ค ์คํํด์ผ์ง๋ง cell์ด ์ ๋๋ก ๋ฐ๋์์ต๋๋ค.
- ์์) `dequeueReusableCell`๋ฉ์๋๋ฅผ `viewDidLoad` ํธ์ถ ์ํฌ ์, cell์ ์์ ๋ ๋ด์ฉ์ด ๋ฐ์์๋จ
<img src = "https://i.imgur.com/4G85SCL.gif" width=200 height=400>
- ๋๋ฒ๊ทธ ์ค๋ฅ ๋ด์ฉ
> [UIDiffableDataSource]
>
> Diffable data source detected an attempt to insert or append 1 item identifier that already exists in the snapshot.
The existing item identifier will be moved into place instead, but this operation will be more expensive.
For best performance, inserted item identifiers should always be unique.
Set a symbolic breakpoint on BUG_IN_CLIENT_OF_DIFFABLE_DATA_SOURCE__IDENTIFIER_ALREADY_EXISTS to catch this in the debugger.
Item identifier that already exists ...
- ์์ธ
- ๋ฐ์ดํฐ ์์ ์์๋ snapshot์ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด์ ์ถ๊ฐ๋ ๋ฐ์ดํฐ๋ ์ถฉ๋์ด ๋ฌ์ต๋๋ค.
- ์ด ์ถฉ๋๋ก ์ธํด, snapShot์ ๋ฐ์์ ๋์์ง๋ง, dataSource๋ ์ด๋ฏธ cell์ ๋ณด์ฌ์ค ๊ฒ์ผ๋ก ์ธ์ํ์ฌ `dequeueReusableCell` ๋ฉ์๋๋ฅผ ์๋์ ์ผ๋ก ํธ์ถํด์ค์ผ๋ง ํ์ต๋๋ค.
- ํด๊ฒฐ ๋ฐฉ์
- snapshot์ ๋ฐ์ดํฐ๋ฅผ `append`ํ๋ ๊ฒฝ์ฐ(์๋ก์ด ์ผ๊ธฐ ์์ฑ)์ snapShot์ ๋ฐ์ดํฐ๋ฅผ `reload`(์ผ๊ธฐ ์์ฑ ์ธ) ํด์ฃผ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋์ด์ฃผ์์ต๋๋ค.
### 2. UX๋ฅผ ๊ณ ๋ คํ์ฌ ์
์ ๋ณด์ฌ์ง๋ title๊ณผ body ์์
- ๋ฌธ์ ์ํฉ
- ํ๋ก์ ํธ ์๊ตฌ์์๋ `/n/n`์ ๊ธฐ์ค์ผ๋ก `title`๊ณผ `body`๋ฅผ ๋๋์ด์ฃผ๋๋ก ๋์์์์ต๋๋ค.
- `\n\n`์ด ์๋ ๊ฒฝ์ฐ์๋ ์ ๋๋ก ์ ์ฅ์ด ๋์ง ์๋ ์ํฉ์ด ๋ฐ์ํ์ต๋๋ค.
#### PR ์ง๋ฌธ์ฌํญ
> ์๊ตฌ์์ ์์ ํ๋ฉด์ ์ฐธ๊ณ ํ์ฌ, `textView`์์ `\n\n`์ ๊ธฐ์ค์ผ๋ก `title`๊ณผ `body`๋ฅผ ๊ตฌ๋ถํด์ฃผ์์ต๋๋ค. `textView`์ `\n\n`์ด ์๋ ๊ฒฝ์ฐ CoreData์ ์ ๋๋ก ์ ์ฅ๋์ง ์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
>
>์ด ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด `\n\n`์ผ๋ก `components` ํด ์ฃผ์์ ๊ฒฝ์ฐ, ๋ฐฐ์ด์ ๊ฐ์๊ฐ 2๊ฐ ์ด์์ธ์ง ํ์ธํ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ฌ, 2๊ฐ ๋ฏธ๋ง์ด๋ฉด ์์๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๋๋ก ํ์ต๋๋ค.
๋ํ `title`์ `\n`์ด ๋ค์ด๊ฐ ๊ฒฝ์ฐ, ์
์์ ์ ๋ชฉ์ด ์๋ฆฌ๋ ํ์์ด ๋ฐ์ํด `\n` ๋์ `" "` ๊ณต๋ฐฑ์ผ๋ก ๋ฐ๊ฟ์ฃผ์์ต๋๋ค. ์ฌ์ฉ์ ์
๋ ฅ์ ์์๋ก ๋ฐ๊ฟ์ค์ผ๋ก์จ ์ฌ์ฉ์๊ฐ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ถฉ์กฑ์์ผ์ฃผ์ง ๋ชปํ ์๋ ์์ ๊ฒ ๊ฐ์ ์ข์ ์ฝ๋๋ผ๋ ์๊ฐ์ด ๋ค์ง ์์ต๋๋ค..๐ ๋ ๋์ ๋ฐฉ์์ผ๋ก `title`๊ณผ `body`๋ฅผ ๊ตฌ๋ถํ๊ณ , ์์ธ์ฒ๋ฆฌ๋ฅผ ํด ์ฃผ๊ณ ์ถ์๋ฐ ์ด๋ค ์์ด๋์ด๋ก ์ ๊ทผํด๋ณด๋ฉด ์ข์์ง ๊ถ๊ธํฉ๋๋ค!
#### ๋ฆฌํฉํ ๋งํ ๊ฒฐ๊ณผ
`/n/n`์ด ์๋๋ผ๋ ๊ตฌ๋ถ์ ํด์ ์ ์ฅํด์ฃผ๋๋ก ์ฌ์ฉ์ UX๋ฅผ ๊ณ ๋ คํ์ฌ ์ถ๊ฐ์ ์ผ๋ก ๋ฆฌํฉํ ๋ง์ ํด๋ณด์์ต๋๋ค.
- ์์
- `\n\n\n\n\n ์ํค๊ณผ ํ์ด์ ์ผ๊ธฐ์ฅ \n`
- ๊ณ ๋ฏผ ์ฌํญ
- \n์ด ๋ฆฌ์คํธ์์ ํด๋น ์ผ๊ธฐ์ฅ์ ์ ๋ชฉ์ผ๋ก ๋ณด์ฌ์ ธ์ผํ๋์ง
- ์ํค๊ณผ ํ์ด์ ์ผ๊ธฐ์ฅ์ด ์ ๋ชฉ์ผ๋ก ๋ณด์ฌ์ ธ์ผํ๋์ง
- ์ผ๊ธฐ์ฅ ์์ธ์ ๋ค์ด์์ ๋ `\n\n\n\n\n` ๋ค์ด ๋ณด์ฌ์ง๊ณ ์ํค๊ณผ ํ์ด์ ์ผ๊ธฐ์ฅ์ด ๋์์ผํ๋์ง
- ํด๊ฒฐ์
- > `์ผ๊ธฐ์ ๋งจ ์ฒซ ์ค์ ์ผ๊ธฐ์ ์ ๋ชฉ์ด ๋๊ณ , ๊ทธ ๋ค์ ์ค๋ถํฐ ๋ณธ๋ฌธ์ด ๋ฉ๋๋ค.`
- ์ ๋ช
์ธ์ ๋ฌธ์๋ง ์
์ ๋ณด์ฌ์ง๋ ๊ฒ์ด ์ฌ์ฉ์๊ฐ ๊ฐ์ฅ ๊ธฐ๋ํ๋ UX๊ฐ ์๋๊น ์ถ์์ต๋๋ค.
- ์ ์ดํฌ์ ์กฐ์ธ์ ๋ฐ๋ผ ๋ค์๊ณผ ๊ฐ์ด ๋ฆฌํฉํ ๋ง์ ์งํํ์ฌ ๊ณ ๋ฏผ์ ํด๊ฒฐํ์ต๋๋ค.
- list์์ ๋ณด์ฌ์ ธ์ผํ๋ ์ ๋ชฉ
- `์ํค๊ณผ ํ์ด์ ์ผ๊ธฐ์ฅ`
- ์ผ๊ธฐ ์์ธ๋ก ๋ค์ด์์ ๋
- `\n\n\n\n\n`์ด ๋ํ๋ ์ดํ ์ํค๊ณผ ํ์ด์ ์ผ๊ธฐ์ฅ์ด ๋ณด์ฌ์ง
---
### ๐ ์ฐธ๊ณ ๋ฌธ์
- [UICollectionViewDiffableDataSource](https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource)
- [NSDiffableDataSourceSnapshot](https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesnapshot)
- [Core Data](https://developer.apple.com/documentation/coredata)
- [Making Apps with Core Data](https://developer.apple.com/videos/play/wwdc2019/230/)
- [UIActivityViewController](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller)
- [LocalizedError](https://developer.apple.com/documentation/foundation/localizederror)
- [resignFirstResponder](https://developer.apple.com/documentation/uikit/uiresponder/1621097-resignfirstresponder)