![](https://hackmd.io/_uploads/r1XRpaBkp.png) # <img src = "https://hackmd.io/_uploads/B1r7f2cya.png" width = "35"> ํ”„๋กœ์ ํŠธ ๋งค๋‹ˆ์ € ## Ground Rules ### ๐Ÿ“ข ์Šคํฌ๋Ÿผ - ์˜ค์ „ 9์‹œ 30๋ถ„์— ๋””์Šค์ฝ”๋“œ์—์„œ ์ง„ํ–‰ - ์ž ๊นจ๊ธฐ - ๊ธˆ์ผ ์ง„ํ–‰ ์‚ฌํ•ญ ๊ณต์œ ํ•˜๊ธฐ(์˜ค๋Š˜์˜ ํ• ์ผ) ### ๐Ÿ“– ํ”„๋กœ์ ํŠธ ๊ทœ์น™ - ๋„ค์ด๋ฐ ์ค€์ˆ˜ํ•˜๊ธฐ(๊ฐ€์ด๋“œ ๋ผ์ธ) - ๋ธŒ๋žœ์น˜ - main - ์ œ์ถœ - step1, step2 - ์šฐ๋ฆฌ๊ฐ€ ์ž‘์—…ํ•  - whales, minsup - ์ฝ”๋“œ์— ๋Œ€ํ•œ ๊ธฐ๋ก ๊ทธ๋•Œ๊ทธ๋•Œ ํ•˜๊ธฐ - ์ค‘๊ฐ„์ค‘๊ฐ„ ๋ฆฌ๋“œ๋ฏธ ์ž‘์„ฑ - ํƒ€์ž… ์ƒ์„ฑ์ž๋กœ ์ƒ์„ฑ๋œ ํ”„๋กœํผํ‹ฐ๋Š” ํƒ€์ž… ์ƒ๋žต ### โœ๏ธ ์ปค๋ฐ‹ ๊ทœ์น™ - ๊นƒ๋ชจ์ง€ - โœจ Feat: ๊ธฐ๋Šฅ ์ถ”๊ฐ€ - โ™ป๏ธ Refactor: ๊ธฐ๋Šฅ๊ณผ ๊ด€๋ จ๋œ ๊ฐœ์„ /์ „๋ฉด์ˆ˜์ • - ๐Ÿฉน Chore: ๋นŒ๋“œ ์—…๋ฌด ์ˆ˜์ •, ํŒจํ‚ค์ง€ ๊ด€๋ จ ์ˆ˜์ •, ํ™˜๊ฒฝ ์„ค์ • ๋“ฑ - ๐Ÿ› Fix: ์˜ค๋ฅ˜ ์ˆ˜์ • - ๐Ÿ’„ Style: ๋„ค์ด๋ฐ, ์ปจ๋ฒค์…˜, ํฌ๋ฉง ์ˆ˜์ • - ๐Ÿ“ Docs: ๋ฌธ์„œ ์ถ”๊ฐ€ ๋ฐ ์ˆ˜์ • - โœ… Test: ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ - ์ปค๋ฐ‹ ๋‹จ์œ„: ๊ธฐ๋Šฅ ๋‹จ์œ„, chore ๋ฌถ์–ด์„œ ์ปค๋ฐ‹ ### ๐Ÿ‘ฉ๐Ÿปโ€โš–๏ธ ํŒ€ ๊ทœ์น™ - TIL, ์ผ์ผ ํšŒ๊ณ  ์ž‘์„ฑ ์‹œ๊ฐ„(๋งค์ผ 22์‹œ๋ถ€ํ„ฐ 1์‹œ๊ฐ„ ์ž‘์„ฑ ์ง„ํ–‰) - ์ปจ๋””์…˜์ด ์ข‹์ง€ ์•Š์„ ๋•Œ๋Š” ๊ผญ ๋งํ•ด์ฃผ๊ธฐ!! - ๋ฐฉํ•ด๊ธˆ์ง€์‹œ๊ฐ„ : 2์‹œ - 9์‹œ ### ๐Ÿ”– ์Šค์ผ€์ค„ - ์›”๋ชฉ | ์‹œ๊ฐ„ | ๋‚ด์šฉ | ์ƒ์„ธ | | :--------: | :--------: | :--------: | | 09:30-10:00 | ์Šคํฌ๋Ÿผ | | | 10:00-12:00 | **ํ™œ๋™ํ•™์Šต ์˜ˆ์Šต** | | | 14:00-17:00 | **ํ™œ๋™ํ•™์Šต** | | | 19:00-22:00 | ํ”„๋กœ์ ํŠธ | ํ•„์š”์‹œ ๊ฐœ์ธ๊ณต๋ถ€ | | ๊ทธ ํ›„ | TIL ๋ฐ ๊ฐœ์ธ์‹œ๊ฐ„ | | - ํ™”์ˆ˜๊ธˆ | ์‹œ๊ฐ„ | ๋‚ด์šฉ | ์ƒ์„ธ | | :--------: | :--------: | :--------: | | 09:30-10:00 | ์Šคํฌ๋Ÿผ | | | 10:00-12:00 | ํ”„๋กœ์ ํŠธ | | | 14:00-17:00 | ํ”„๋กœ์ ํŠธ ๋ฐ ๊ฐœ์ธ๊ณต๋ถ€ | | | 19:00-22:00 | ๊ฐœ์ธ๊ณต๋ถ€ | ํ•„์š”์‹œ ํ”„๋กœ์ ํŠธ | | ๊ทธ ํ›„ | TIL ๋ฐ ๊ฐœ์ธ์‹œ๊ฐ„ | | - ์˜ˆ์™ธ์‚ฌํ•ญ - ์•ผ์•„ํ†ค: 10.5-6 - ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ›์œผ๋ฉด ์œ ๋™์ ์œผ๋กœ! - ์ถ”์„ ๋ชฉ๊ธˆ OffDay ## ์ผ์ผ ์Šคํฌ๋Ÿผ ### ๐Ÿ™Œ 09/18 ์›” - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ๋„ˆ๋ฌด ํž˜๋“  ํ•˜๋ฃจ...๐Ÿซ  - Whales๐Ÿฌ: ์ž˜ ์ž๊ณ  ์ž˜ ์‰ฌ๊ณ  ๋ง์งฑํ•ฉ๋‹ˆ๋‹ค!! - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ์—†์Šต๋‹ˆ๋‹ค! - Whales๐Ÿฌ: ์ปด๋ฐ”์ธ ๋„ˆ๋ฌด ์–ด๋ ค์›Œ์š”..๐Ÿคฏ - ์˜ค๋Š˜ ํ•  ์ผ - [x] ๊ทธ๋ผ์šด๋“œ ๋ฃฐ - [x] ๊ธฐ์ˆ  ์Šคํƒ ์ƒ์˜ํ•˜๊ธฐ ### ๐Ÿ™Œ 09/19 ํ™” - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์•ฝ๊ฐ„ ํ”ผ๊ณค...? - Whales๐Ÿฌ: ์•ˆ ์กธ๋ฆฝ๋‹ˆ๋‹ค...?! - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ์—†์Šต๋‹ˆ๋‹ค! - Whales๐Ÿฌ: ์ €๋„ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌด๋‚œ๋ฌด๋‚œํ•œ ํ•˜๋ฃจ!! - ์˜ค๋Š˜ ํ•  ์ผ - [x] ๊ทธ๋ฆฐ๊ณผ ๊ธฐ์ˆ  ์Šคํƒ ์ƒ์˜ํ•ด์„œ ์ •ํ•˜๊ธฐ (์˜คํ›„ 2์‹œ) - [x] ๋ชฉํ‘œ - STEP 1 PR ๋ณด๋‚ด๊ธฐ ### ๐Ÿ™Œ 09/20 ์ˆ˜ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ƒ์พŒํ•˜์ง„ ์•Š์ง€๋งŒ..์ข‹์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ํ‘น ์ž˜์ž์„œ ์•„์ฃผ ์ƒ์พŒํ•ฉ๋‹ˆ๋‹ค. - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ๋ชจ๊ฐ์ฝ”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค - Whales๐Ÿฌ: ์—ญ์‹œ ์‚ฌ๋žŒ์€ ์ž ์„ ์ž˜ ์ž์•ผํ•ฉ๋‹ˆ๋‹ค. - ์˜ค๋Š˜ ํ•  ์ผ - [x] SwiftUI ๋งŒ์ ธ๋ณด๊ธฐ - [x] Step2 ์‹œ์ž‘ 2:30 ### ๐Ÿ™Œ 09/21 ๋ชฉ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ข‹์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ์˜ค๋Š˜์€ ๋„ˆ๋ฌด๋„ˆ๋ฌด ์กธ๋ฆฝ๋‹ˆ๋‹ค - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ์—†์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ์—ด์‹ฌํžˆ ๊ณต๋ถ€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค!!! - ์˜ค๋Š˜ ํ•  ์ผ - [x] ํ™œ๋™ํ•™์Šต - [x] Step2 ์ชผ๊ฐœ๋ณด๊ธฐ (์ถ”๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„๊นŒ์ง€๊ฐ€ 2-1) - [x] Whales - ๋„์ „!! ํ˜ผ์ž์„œ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ - [x] Minsup - ์•„ํ‚คํ…์ฒ˜ ๊ณ ๋ฏผ. ํŒŒ์ผ๊ตฌ์กฐ, ๋ธŒ๋žœ์น˜, ๋จธ์ง€ ๋“ฑ - [x] MVVM ์ ์šฉ ### ๐Ÿ™Œ 09/22 ๊ธˆ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ž˜ ์žค์Šต๋‹ˆ๋‹ค~~ - Whales๐Ÿฌ: ์ž ์ด ๋ถ€์กฑํ•จ์ด ๋А๊ปด์ง‘๋‹ˆ๋‹ค์•„ - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: PR ๋„์ „ - Whales๐Ÿฌ: ๋‹ค์‹œ ์Šค์œ  ๋„์ „!! ์œผ์Œฐ์œผ์Œฐ!! - ์˜ค๋Š˜ ํ•  ์ผ - [x] Whales - Environment ํ‚ค์›Œ๋“œ๋กœ ๋‹ค์‹œ ๋„์ „!! - [x] README - [x] Minsup - Refactoring ### ๐Ÿ™Œ 09/25 ์›” - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ข‹์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ๋ชธ์ด ์œผ์Šฌ์œผ์Šฌ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค๐Ÿ˜“ - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ์—†์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ํ•˜๋ฃจ๋ฅผ ๋‚ ๋ ค๋จน์—ˆ์Šต๋‹ˆ๋‹ค์•„....๐Ÿซ  - ์˜ค๋Š˜ ํ•  ์ผ - [x] ํ™œ๋™ํ•™์Šต ### ๐Ÿ™Œ 09/26 ํ™” - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ข‹์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ๋ชธ์ด ์•ˆ ์ข‹์€๊ฑด ๊ดœ์ฐฎ์€๋ฐ ์•„์ฃผ์•„์ฃผ ํ”ผ๊ณคํ•˜๋„ค์š” - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ์ €๋…์•ฝ์† - Whales๐Ÿฌ: ๋น„๊ฐ€ ์˜ต๋‹ˆ๋‹ค....๋น„๊ฐ€ ์™€์š”์˜ค.... - ์˜ค๋Š˜ ํ•  ์ผ - [x] ๋ฆฌ๋ทฐ ๋ฐ›์€ ๋ถ€๋ถ„ ์ˆ˜์ • ### ๐Ÿ™Œ 09/27 ์ˆ˜ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ข‹์Šต๋‹ˆ๋‹ค. ํ–‰๋ณตํ•ฉ๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ๋Šฆ์ž ....์žค์Šต๋‹ˆ๋‹ค? - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ์—†์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: Async / Await...์–ด๋ ค์›Œ์š”..... - ์˜ค๋Š˜ ํ•  ์ผ - [x] ํ™œ๋™ํ•™์Šต - [x] Whales - ๋ฉ˜ํ† ๋ง - [x] Minsup - 2์ฐจ ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜ ### ๐Ÿ™Œ 10/01 ์ผ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ข‹์Šต๋‹ˆ๋‹ค. ํ–‰๋ณตํ•ฉ๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ํ‘น ์ž˜์ž๊ณ  ์•„์ฃผ ์ž˜ ์‰ฌ์—ˆ์Šต๋‹ˆ๋‹ค. - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ์—†์Šต๋‹ˆ๋‹ค. - Whales๐Ÿฌ: ์–ธ๋‹ˆ๋„ค ์ง‘ ๊ฐ”๋‹ค ์™”์Šต๋‹ˆ๋‹ค ํ—คํ—ฟ - ์˜ค๋Š˜ ํ•  ์ผ - [x] STEP 2-2 PR ๋ณด๋‚ด๊ธฐ - [x] README ์ถ”๊ฐ€ ์ž‘์„ฑ ### ๐Ÿ™Œ 10/03 ํ™” - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ์ข‹์Šต๋‹ˆ๋‹ค!! - Whales๐Ÿฌ: ์•„๋ฌด๋ž˜๋„ ๊ฐ๊ธฐ๊ฐ€ ์˜ค๋ ค๋‚˜ ๋ด…๋‹ˆ๋‹ค์•„์•„์•„ - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ๋Šฆ์ž ... - Whales๐Ÿฌ: ๋ฏผ์„ญ ๋Šฆ์ž ์ด์‹œ๋ฉด ์ €๋„ ์ข€ ๋” ์ž๊ณ ์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค ํ•˜ํ•ณ - ์˜ค๋Š˜ ํ•  ์ผ - [x] STEP 2-2 ๋ฆฌ๋ทฐ ๋ฐ›์€ ๋ถ€๋ถ„ ์ˆ˜์ •ํ•˜๊ธฐ - [x] STEP3 ์‹œ์ž‘! - Realm ๊ณต๋ถ€ ### ๐Ÿ™Œ 10/04 ์ˆ˜ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: ๋งค์šฐ ์กธ๋ฆฝ๋‹ˆ๋‹ค? - Whales๐Ÿฌ: ํ‘น ์ž˜์ž์„œ ์•„์ฃผ ๊ฐœ์šดํ•ฉ๋‹ˆ๋‹ค!!! - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: ๋””์ž์ธ ํŒจํ„ด ๊ณต๋ถ€ํ•˜๊ณ  ๋ฐœํ‘œ์ค€๋น„๋ฅผ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. 10์‹œ์ฏค? - Whales๐Ÿฌ: Realm ๋„ˆ๋ฌด ์–ด๋ ค์›Œ์š”.. MVVM ํŠน๊ฐ• ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค!!! - ์˜ค๋Š˜ ํ•  ์ผ - [ ] Realm ์ ์šฉ - [ ] MVVM ํŠน๊ฐ• - [ ] PR step3 ๋„์ „(?) ### ๐Ÿ™Œ 10/05 ๋ชฉ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: - Whales๐Ÿฌ: ์˜ค๋Š˜์€ ๋งค์šฐ๋งค์šฐ ํ”ผ๊ณคํ•ฉ๋‹ˆ๋‹ค์•„์•„์•„์•„์•„์•„ - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: - Whales๐Ÿฌ: ๋””์ž์ธํŒจํ„ด ๋ฐœํ‘œ!! ๋–จ๋ฆฝ๋‹ˆ๋‹ค ํ›„ํ•˜ํ›„ํ•˜ - ์˜ค๋Š˜ ํ•  ์ผ - [ ] ๋””์ž์ธํŒจํ„ด ๋ฐœํ‘œ ์ค€๋น„ - [ ] ํ™œ๋™ํ•™์Šต - ๋””์ž์ธํŒจํ„ด ๋ฐœํ‘œ - [ ] Whales - ์•ผ์•„ํ†ค (์˜คํ›„ 4:30~) - [ ] Minsup - STEP 3 ### ๐Ÿ™Œ 10/06 ๊ธˆ - ์˜ค๋Š˜์˜ ์ปจ๋””์…˜ - Minsup๐ŸฆŠ: - Whales๐Ÿฌ: - ํŠน์ด์‚ฌํ•ญ - Minsup๐ŸฆŠ: - Whales๐Ÿฌ: - ์˜ค๋Š˜ ํ•  ์ผ - [ ] Whales - ์•ผ์•„ํ†ค (~์˜คํ›„ 4:30), ๋ฉ˜ํ† ๋ง(๋ฐค 10~12์‹œ) - [ ] - [ ] # <img src = "https://hackmd.io/_uploads/B1r7f2cya.png" width = "35"> ํ”„๋กœ์ ํŠธ ๋งค๋‹ˆ์ € <img src = "https://hackmd.io/_uploads/Bkf_435kT.png" width = "30"><img src = "https://hackmd.io/_uploads/rJhCN3qkp.png" width = "30"> - ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: [2023๋…„ 9์›” 18์ผ ~ 10์›” 6์ผ](https://github.com/WhalesJin/ios-project-manager/wiki/ํƒ€์ž„๋ผ์ธ) - ํ”„๋กœ์ ํŠธ ํŒ€์›: [Whales <img src = "https://hackmd.io/_uploads/Bkf_435kT.png" width = "20">](https://github.com/WhalesJin) , [Minsup <img src = "https://hackmd.io/_uploads/rJhCN3qkp.png" width = "20">](https://github.com/agilestarskim) - ํ”„๋กœ์ ํŠธ ๋ฆฌ๋ทฐ์–ด: [GREEN <img src = "https://hackmd.io/_uploads/H1pGWNoyp.png" width = "20">](https://github.com/GREENOVER) --- ## ๐Ÿ“– ๋ชฉ์ฐจ ๐Ÿ€ [์†Œ๊ฐœ](#์†Œ๊ฐœ) </br> ๐Ÿ’ป [์‹คํ–‰ ํ™”๋ฉด](#์‹คํ–‰_ํ™”๋ฉด) </br> ๐Ÿ› ๏ธ [์‚ฌ์šฉ ๊ธฐ์ˆ ](#์‚ฌ์šฉ_๊ธฐ์ˆ ) </br> ๐Ÿ‘€ [๋‹ค์ด์–ด๊ทธ๋žจ](#Diagram) </br> ๐Ÿงจ [ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…](#ํŠธ๋Ÿฌ๋ธ”_์ŠˆํŒ…) </br> ๐Ÿ“š [์ฐธ๊ณ  ๋งํฌ](#์ฐธ๊ณ _๋งํฌ) </br> ๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง [about TEAM](#about_TEAM) </br> </br> ## ๐Ÿ€ ์†Œ๊ฐœ<a id="์†Œ๊ฐœ"></a> <img src = "https://hackmd.io/_uploads/Bkf_435kT.png" width = "20"><img src = "https://hackmd.io/_uploads/rJhCN3qkp.png" width = "20"> : ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์„ธ๋ถ„ํ™”ํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค. ์นธ๋ฐ˜๋ณด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ TODO, DOING, DONE์œผ๋กœ ๋ถ„๋ฅ˜ํ•ด ์ง„ํ–‰๋„๋ฅผ ํ•œ ๋ˆˆ์— ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์…€์„ ๊ธธ๊ฒŒ ํด๋ฆญํ•˜์—ฌ ํ•  ์ผ์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ณ  ์Šค์™€์ดํ”„๋ฅผ ํ†ตํ•ด ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ๋‹จ ๋ฐ”์— ์œ„์น˜ํ•œ + ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ƒˆ๋กœ์šด ์…€์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด์˜ ์…€์„ ํด๋ฆญํ•˜์—ฌ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </br> ## ๐Ÿ’ป ์‹คํ–‰ ํ™”๋ฉด<a id="์‹คํ–‰_ํ™”๋ฉด"></a> | ๊ธฐ๋ณธ ํ™”๋ฉด | | :--------: | | <img src = "https://hackmd.io/_uploads/BkzTn1Pga.png" width = "600"> | | ์ƒˆ ํ•  ์ผ ์ถ”๊ฐ€ | | :--------: | | <img src = "https://hackmd.io/_uploads/rJC22ywgp.gif" width = "600"> | | ๊ธฐ์กด ํ•  ์ผ ํŽธ์ง‘ | | :--------: | | <img src = "https://hackmd.io/_uploads/ByIcjJwlp.gif" width = "600"> | | ์นดํ…Œ๊ณ ๋ฆฌ ๋ณ€๊ฒฝ | | :--------: | | <img src = "https://hackmd.io/_uploads/r18qskPlT.gif" width = "600"> | </br> ## ๐Ÿ› ๏ธ ์‚ฌ์šฉ ๊ธฐ์ˆ <a id="์‚ฌ์šฉ_๊ธฐ์ˆ "></a> | ๊ตฌํ˜„ ๋‚ด์šฉ | ๋„๊ตฌ | |:---:|:---:| |UI|SwiftUI| |์•„ํ‚คํ…์ณ|ํด๋ฆฐ ์•„ํ‚คํ…์ณ| |๋””์ž์ธํŒจํ„ด|MVVM| |๋กœ์ปฌ ๋ฐ์ดํ„ฐ|Realm| |๋ฆฌ๋ชจํŠธ ๋ฐ์ดํ„ฐ|Firebase| </br> ## ๐Ÿ‘€ Diagram<a id="Diagram"></a> ### ๐Ÿ“ UML <img src = "https://hackmd.io/_uploads/HkGA5h9y6.png" width = "800"> </br> # Separator ## ๐Ÿงจ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…<a id="ํŠธ๋Ÿฌ๋ธ”_์ŠˆํŒ…"></a> ### 1๏ธโƒฃ ๊ธฐ์ˆ ์Šคํƒ ์„ค์ • #### 1. ๋ทฐ ๋“œ๋กœ์ž‰ - SwiftUI UIKit์— ๋น„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์„ ๋А๊ปด์„œ SwiftUI๋กœ ์„ ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. - ๋ทฐ ๊ทธ๋ฆฌ๊ธฐ ๊ฐ„๋‹จํ•˜๋‹ค. - ๋ ˆ์ด์•„์›ƒ ๋งŽ์ด ์‹œ๊ฐ„ ์•ˆ ๋บ๊น€ - ์ฝ”๋“œ๊ฐ€ ์งง๊ณ  ์ง๊ด€์ ์ด๋‹ค. - ์žฌ๋ฐŒ๋‹ค. #### 2. ์•„ํ‚คํ…์ฒ˜ - ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜ + MVVM ํ”„๋กœ์ ํŠธ๋“ค์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์ฒด๊ณ„๋„ ์—†๋Š” ๊ฒƒ ๊ฐ™๊ณ , ๋ณต์žก์„ฑ์ด ๋งŽ์ด ์–ฝํ˜€์žˆ๋Š” ๋А๋‚Œ์ด๋ผ ์ด๋ ‡๊ฒŒ ์ค‘๊ตฌ๋‚œ๋ฐฉํ•˜์ง€์•Š๊ณ  ๊ทœ์น™์ด ์žˆ๊ฑฐ๋‚˜ ์˜์กด๋ฐฉํ–ฅ์ด ์ผ์ •ํ–ˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์˜์กด์„ฑ ๊ทœ์น™์— ๋Œ€ํ•œ ์–˜๊ธฐ๋ฅผ ํ•˜๋Š” `ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜`๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜๋Š” ์ด๋ก ์ ์ด๊ณ  ์ถ”์ƒ์ ์ธ ๋А๋‚Œ์ด๋ผ ๋ฐฉ๋ฒ•์ด ๋˜๊ฒŒ ๋‹ค์–‘ํ•ด ๋ณด์˜€๊ณ , ๊ทธ ์ค‘์—์„œ๋„ ์ €ํฌ๋Š” MVVM์„ ์ ‘๋ชฉํ•ด์„œ **ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ MVVM**์„ ๊ตฌํ˜„ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. #### 3. ๋กœ์ปฌ๋ฐ์ดํ„ฐ - Realm CoreData์— ๋น„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ๋“ค์ด ๋” ์™€๋‹ฟ์•„์„œ Realm์œผ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. - ์†๋„๊ฐ€ CoreData๋ณด๋‹ค ํ›จ์”ฌ ๋น ๋ฅด๋‹ค. - ์ง๊ด€์ ์ธ API๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด ์‚ฌ์šฉ์„ฑ์ด ์ข‹๋‹ค. - ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ธด ํ•˜์ง€๋งŒ MongoDB๊ฐ€ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์–ด ์‹ ๋ขฐ์„ฑ์ด ๋†’๋‹ค. - ๋ฌธ์„œ ์ •๋ฆฌ๊ฐ€ ์ž˜ ๋˜์–ด์žˆ๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์ž˜ ์ƒ์„ฑ๋˜์–ด์žˆ์–ด ์ •๋ณด ์Šต๋“์ด ๋น ๋ฅด๋‹ค. - SPM์„ ์ง€์›ํ•œ๋‹ค. - Entity Mappingํ•  ๋•Œ CoreData๋ณด๋‹ค ํ›จ์”ฌ ํŽธํ•˜๋‹ค. -> CoreData๋Š” ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ context๊ฐ€ ํ•„์š”ํ•˜๋‹ค. #### 4. ๋ฆฌ๋ชจํŠธ๋ฐ์ดํ„ฐ - Firebase iCloud์™€ Firebase ์ค‘์— ๊ณ ๋ฏผ์ด ๋˜์–ด ๋‘ ๊ฐ€์ง€๋ฅผ ๋น„๊ตํ•ด๋ณด๊ณ  ๊ฒฐ๋ก ์ ์œผ๋กœ Firebase๊ฐ€ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์—๋Š” ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํŒ๋‹จํ•ด์„œ Firebase๋กœ ์„ ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. <img src = "https://hackmd.io/_uploads/H18Ofyvyp.png" width = 80> - ํŽธ์˜์„ฑ์ด ์ข‹๋‹ค. CoreData์™€์˜ ์—ฐ๋™์ด ์ข‹๋‹ค. ์ฝ”์–ด๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค ์‚ฌ์šฉ [NSPersistentCloudKitContainer](https://developer.apple.com/documentation/coredata/nspersistentcloudkitcontainer) - iCloud๋Š” ์ œ๊ณต์ด ์•ฝํ•˜๋‹ค. - iCloud ๊ณ„์ •์„ ์“ฐ๋ฏ€๋กœ ์นœ๊ตฌ๊ฐ€ ๋˜์–ด์žˆ์œผ๋ฉด ์ €์žฅ ์œ„์น˜์— ๋”ฐ๋ผ ์ ‘๊ทผ ์ˆ˜์ค€์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. - ์˜์กด์„ฑ ๊ด€๋ฆฌ๋„๊ตฌ ํ•„์š”์—†๋‹ค. - [CloudKit](https://developer.apple.com/kr/icloud/cloudkit/) <img src = "https://hackmd.io/_uploads/SyrlGJDy6.png" width = 110> - ์•ˆ๋“œ๋กœ์ด๋“œ๋ž‘ ๊ฐ™์ด ๊ณต์œ ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. (ํฌํŠธํด๋ฆฌ์˜ค๋กœ ์ข‹๋‹ค) - ๋‹จ์ ์€ ๋น„์‹ธ๋‹ค. - ์˜์กด์„ฑ ๊ด€๋ฆฌ๋„๊ตฌ : ์ฝ”์ฝ”์•„ํŒŸ์ด๋‚˜ **SPM** - ์•ˆ๋“œ๋กœ์ด๋“œ ์ปค๋ฒ„๋‚˜ ์ปค๋ฆฌ์–ด โ†’ Firebase - ์ œ๊ณตํ•ด์ฃผ๋Š” ์„œ๋น„์Šค๊ฐ€ ๋งŽ๋‹ค. All in One - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ž‘ ์…‹ํŒ…์ด ๋‹ค ๋˜์–ด์žˆ๋‹ค. - ๋ณด์•ˆ ์†”๋ฃจ์…˜๋„ ๋‹ค ์„ค์น˜๋˜์–ด์žˆ๋‹ค. - ๋ฐ์ดํ„ฐ ์„ผํ„ฐ. ์„œ์šธ๋„ ์กด์žฌํ•œ๋‹ค. - ๊ธฐ๋ณธ์š”๊ฑด์ด ์•„๋ž˜์™€ ๊ฐ™์•„์„œ ํ•˜์œ„ ๋ฒ„์ „ ํ˜ธํ™˜๋„ ๋ฌธ์ œ ์—†๋‹ค. - Xcode 14.1 ์ด์ƒ - iOS 11 ์ด์ƒ - ๋‹จ์ : ์ง์ ‘ DB์— ์ ‘๊ทผํ•˜๋‹ˆ๊นŒ ๋ณด์•ˆ์ด ์•ฝํ•˜๋‹ค ### 2๏ธโƒฃ CUSTOM MODIFIER ๐Ÿšจ **๋ฌธ์ œ์ ** <br> Custom View๋ฅผ alert ํ˜•ํƒœ๋กœ ๋„์šฐ๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ๋ชจ์ƒ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ API๋Š” ์ฃผ์–ด์ง€์ง€ ์•Š์•„ ์ง์ ‘ ๊ตฌํ˜„์„ ํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ’ก **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> ZStack์œผ๋กœ ๋ฐฐ๊ฒฝ๊ณผ alert์„ ๋‚˜๋ˆ„๊ณ  ๊ทธ ์‚ฌ์ด์— ๊ฒ€์€ ๋ถˆํˆฌ๋ช… ๋ทฐ๋ฅผ ๋„ฃ์–ด alert์ด ๋„์–ด์žˆ๋Š” ํšจ๊ณผ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. binding์„ ์ด์šฉํ•ด ์ตœ๋Œ€ํ•œ SwiftUI API์™€ ๋น„์Šทํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. <br> ### 3๏ธโƒฃ ViewModel ์„ ์–ธ ๋ฐฉ์‹ ๐Ÿšจ **๋ฌธ์ œ์ ** <br> ์ฒ˜์Œ์—” ์•„๋ž˜์™€ ๊ฐ™์ด ViewModel์„ ๊ฐ View ์•ˆ์— ์ค‘์ฒฉํƒ€์ž…์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ViewModel์ด๋ž€ ์ด๋ฆ„์„ ๊ฐ ๋ทฐ์—์„œ ์ค‘๋ณตํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ View์—์„œ ๋‹ค๋ฅธ View์˜ViewModel์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋ทฐ์ด๋ฆ„.๋ทฐ๋ชจ๋ธ ์ด๋Ÿฐ์‹์œผ๋กœ ์ ‘๊ทผํ•ด์•ผํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ```swift extension KanbanView { final class ViewModel: ObservableObject { ... } } struct KanbanView: View { @ObservedObject var vm = ViewModel() ... } ``` ๐Ÿ’ก **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> ์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ๋” ๋”ฐ๋กœ ๋นผ๋‚ด์–ด ํƒ€์ž…์„ ์ƒ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. ```swift final class KanbanViewModel: ObservableObject { } ``` <br> ### 4๏ธโƒฃ TaskFormView ์žฌํ™œ์šฉ ๐Ÿšจ **๋ฌธ์ œ์ ** <br> TaskFormView์—์„œ Create์™€ Edit์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ค‘๋ณต๋œ ๋ถ€๋ถ„๋“ค์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ๊นŒ ๊ณ ๋ฏผํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ’ก **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> 1๏ธโƒฃ View์˜ init์—์„œ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ view๋ฅผ initํ•  ๋•Œ optinal Task๋ฅผ ์‚ฌ์šฉํ•ด, create์ผ ๊ฒฝ์šฐ nil, edit์ผ ๊ฒฝ์šฐ ์ˆ˜์ •ํ•  task๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋‹จ์ ์€ init์— ๋กœ์ง์ด ๋“ค์–ด๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ  ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ์ˆ˜์ •ํ•  ๋ถ€๋ถ„๋„ ๋งŽ์•„์ง€๊ณ  ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๋ฉ”์†Œ๋“œ๋“ค์„ viewModel์— ๋ชจ๋‘ ์ง‘์–ด๋„ฃ์–ด์•ผํ•œ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. [Optional Task๋ฅผ ์ด์šฉ](https://github.com/WhalesJin/ios-project-manager/blob/f2d72324a03fabdb7f51d02ce3442bcc2aaa28e3/ProjectManager/ProjectManager/Presentation/Kanban/TaskForm/TaskFormView.swift) 2๏ธโƒฃ Protocol์„ ์ด์šฉํ•ด ๊ตฌํ˜„ํ•˜๊ธฐ Create์™€ Edit์„ ๊ด€์ฐฐํ•ด๋ณด๋‹ˆ ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„์ด ๋งŽ์•„์„œ ํ”„๋กœํ† ์ฝœ๋กœ ๊ธฐ๋Šฅ ์ •์˜ ํ›„ Create์™€ Edit์˜ ViewModel์„ ๊ฐ๊ฐ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์„œ ๋ทฐ๋ชจ๋ธ์„ ์ฃผ์ž…ํ•˜๋Š” ํ˜•์‹์œผ๋กœ ๊ตฌํ˜„ํ•ด๋ดค์Šต๋‹ˆ๋‹ค. ๋‹จ์ ์€ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ๊ฐ ๋ทฐ๋ชจ๋ธ์— ๋˜‘๊ฐ™์€ ๋ฉ”์†Œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์–ต์ง€๋กœ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. [Protocol ์‚ฌ์šฉ](https://github.com/WhalesJin/ios-project-manager/blob/ddea938b958136009b59b3b63a54f7b339904648/ProjectManager/ProjectManager/Presentation/Kanban/TaskForm/TaskFormView.swift) <br> ### 5๏ธโƒฃ Move to ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ ๐Ÿšจ **๋ฌธ์ œ์ ** <br> ๊ธฐ์กด ์ฝ”๋“œ๋Š” todos, doings, dones๋ฅผ ๊ฐ๊ฐ ๋ถ„๋ฆฌ๋œ ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„๋˜์–ด์žˆ์–ด์„œ ํ•œ ๋ฐฐ์—ด์—์„œ ๋‹ค๋ฅธ ๋ฐฐ์—ด๋กœ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๊ธฐ์กด ๋ฐฐ์—ด์—์„œ removeํ•˜๊ณ  ๋‹ค๋ฅธ ๋ฐฐ์—ด์—์„œ append ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰๋˜์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์งœ๊ฒŒ ๋˜๋ฉด ์ƒํƒœ๋ณ€ํ™”์— ๋”ฐ๋ฅธ ๋ฉ”์„œ๋“œ๋“ค์˜ ์ค‘๋ณต์ด ๋Š˜์–ด๋‚˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ฏผํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ```swift func moveFromTodo(task: Task, to other: String) { if other == "DOING" { moveToDoingFromTodo(task: task) } else { moveToDoneFromTodo(task: task) } } func moveToDoingFromTodo(task: Task) { guard let index = todos.firstIndex(of: task) else { return } todos.remove(at: index) doings.append(task) } func moveToDoneFromTodo(task: Task) { guard let index = todos.firstIndex(of: task) else { return } todos.remove(at: index) dones.append(task) } ``` ๐Ÿ’ก **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> 1๏ธโƒฃ state ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด state๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋ฐฐ์—ด์„ ๋ถ„๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์‹ค์ œ๋กœ ์š”์†Œ๋ฅผ ๋‹ค๋ฅธ ๋ฐฐ์—ด๋กœ ์ด๋™์‹œํ‚ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ƒํƒœ๋งŒ ๋ฐ”๊ฟˆ์œผ๋กœ์„œ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ณผ์ •์—์„œ ์›๋ณธ tasks ๋ฐฐ์—ด ์ˆœ์„œ๋Œ€๋กœ ์š”์†Œ๋“ค์ด ๋ณด์—ฌ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ €ํฌ๊ฐ€ ์›ํ•˜๋Š” ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ง€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.๋”ฐ๋ผ์„œ ์š”์†Œ์˜ ์ˆœ์„œ๋ฅผ ์–ด๋–ค ๊ธฐ์ค€์œผ๋กœ ๋ณด์—ฌ์ฃผ์–ด์•ผํ• ์ง€ ๊ธฐํšํ•ด์•ผํ–ˆ๊ณ  ๊ฒฐ๊ตญ date๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค. ```swift @Published var tasks: [Task] var todos: [Task] { return tasks.filter { $0.state == .todo } } var doings: [Task] { return tasks.filter { $0.state == .doing } } var dones: [Task] { return tasks.filter { $0.state == .done } } init(tasks: [Task] = []) { self.tasks = tasks self.tasks.sort { $0.date < $1.date } } func create(_ task: Task) { tasks.append(task) tasks.sort { $0.date < $1.date } } ``` <br> ## ๐Ÿ“š ์ฐธ๊ณ  ๋งํฌ<a id="์ฐธ๊ณ _๋งํฌ"></a> - <Img src = "https://hackmd.io/_uploads/Hyyrii91T.png" width="20"/> [Firebase](https://firebase.google.com/?hl=ko) - <Img src = "https://hackmd.io/_uploads/B1pu3oq1a.png" width="20"/> [Realm ์„ค์น˜](https://www.mongodb.com/docs/realm/sdk/swift/install/#std-label-ios-install) - [๐ŸŽ Apple Docs: CloudKit](https://developer.apple.com/kr/icloud/cloudkit/) - [๐ŸŽ Apple Docs: List](https://developer.apple.com/documentation/swiftui/list) - [๐ŸŽ Apple Docs: ViewModifier](https://developer.apple.com/documentation/swiftui/viewmodifier) - [๐ŸŽ Apple Docs: GeometryReader](https://developer.apple.com/documentation/swiftui/geometryreader) - [๐ŸŽ Apple Docs: ScrollViewReader](https://developer.apple.com/documentation/swiftui/scrollviewreader) - [๐ŸŽ Apple Docs: UnitPoint](https://developer.apple.com/documentation/swiftui/unitpoint) - [๐ŸŽ Apple Docs: ]() - [๐Ÿ WWDC: ]() - [๐Ÿ WWDC: ]() - [๐Ÿ WWDC: ]() - [๐Ÿ“š StackOverflow: ViewModel Protocol](https://stackoverflow.com/questions/59503399/how-to-define-a-protocol-as-a-type-for-a-observedobject-property) - <Img src = "https://github.com/mint3382/ios-calculator-app/assets/124643545/56986ab4-dc23-4e29-bdda-f00ec1db809b" width="20"/> [์•ผ๊ณฐ๋‹ท๋„ท: Test Double](https://yagom.net/courses/unit-test-์ž‘์„ฑํ•˜๊ธฐ/lessons/ํ…Œ์ŠคํŠธ๋ฅผ-์œ„ํ•œ-๊ฐ์ฒด-๋งŒ๋“ค๊ธฐ/topic/ํ…Œ์ŠคํŠธ๋ฅผ-์œ„ํ•œ-๊ฐ์ฒด๋ฅผ-์ด์šฉํ•ด์„œ-ํ…Œ์ŠคํŠธ-์ž‘์„ฑํ•˜๊ธฐ/) - <Img src = "https://hackmd.io/_uploads/ByTEsGUv3.png" width="20"/> [blog: URL ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•](https://ios-development.tistory.com/1014) <br> --- ## ๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง about TEAM<a id="about_TEAM"></a> | <Img src = "https://hackmd.io/_uploads/r1elEh5ka.png" width="100"> | ๐ŸฌWhales๐Ÿฌ | https://github.com/WhalesJin | | :--------: | :--------: | :--------: | | <Img src = "https://hackmd.io/_uploads/HkTfN2cyp.png" width="100"> | **Minsup** | **https://github.com/agilestarskim** | - [ํƒ€์ž„๋ผ์ธ ๋งํฌ](https://github.com/WhalesJin/ios-project-manager/wiki/ํƒ€์ž„๋ผ์ธ) <details> |๋‚ ์งœ|๋‚ด์šฉ| |:--:|--| |2023.09.18(์›”)| - ๊ธฐ์ˆ  ์Šคํƒ ์กฐ์‚ฌ ๋ฐ ๊ฒฐ์ • | |2023.09.19(ํ™”)| - `SwiftUI`๋กœ ํ”„๋กœ์ ํŠธ UI ๋ณ€๊ฒฝ ๋ฐ ์•„์ด์ฝ˜ ์ถ”๊ฐ€ <br> - `Realm` ๋ฐ `Firebase` ํŒจํ‚ค์ง€ ์ถ”๊ฐ€ | |2023.09.20(์ˆ˜)| - `ํด๋ฆฐ์•„ํ‚คํ…์ฒ˜` + `MVVM` ๊ตฌ์กฐ ์ƒ์„ฑ <br> - `CellView`, `ListView`, `TodoView` ๊ตฌํ˜„ | |2023.09.21(๋ชฉ)| - `TaskAddView` ์—ด๊ณ  ๋‹ซ๊ธฐ ๊ตฌํ˜„ | |2023.09.22(๊ธˆ)| - README ์ž‘์„ฑ <br> - `TaskAddView`๋ฅผ `TaskFormView`๋กœ ์ˆ˜์ • ๋ฐ ๋กœ์ง ๊ตฌํ˜„ <br> - Column header์— ์นด๋“œ ๊ฐœ์ˆ˜, ์ง€๋‚œ ๋‚ ์งœ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ํ‘œ์‹œ ๋“ฑ UI ๊ฐœ์„  | |2023.09.26(ํ™”)| - `TaskFormView`์˜ UI ๋ฐ ์ƒ์„ธ ๋กœ์ง ๋ณ€๊ฒฝ <br> - `View`์˜ ๋ฐ˜๋ณต `modifier`๋ฅผ `custom Modifier`๋กœ ๋ถ„๋ฆฌ <br> - ๊ธธ๊ฒŒ ๋ˆŒ๋Ÿฌ ์ƒํƒœ ๋ณ€๊ฒฝ ๋ฐ ์Šค์™€์ดํ”„ ์‚ญ์ œ ๊ตฌํ˜„ | |2023.09.27(์ˆ˜)| - ํ‚ค๋ณด๋“œ๋กœ ์ธํ•ด `TextEditor` ๊ฐ€๋ฆฌ๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ <br> - 2์ฐจ ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜| |2023.09.29(๊ธˆ)| - ์นด๋“œ ํด๋ฆญ ์‹œ `Edit` ๊ธฐ๋Šฅ ์ถ”๊ฐ€ | |2023.09.30(ํ† )| - `separator` ๊ฐ„๊ฒฉ ์ œ๊ฑฐ | </details> </br> ### ๐Ÿ‘ฅ ํŒ€ ํšŒ๊ณ <a id="ํŒ€_ํšŒ๊ณ "></a> - [ํŒ€ ํšŒ๊ณ  ๋งํฌ]() ### ๐Ÿ‘๐Ÿป ์šฐ๋ฆฌํŒ€ ์ž˜ํ•œ ์  ### ๐Ÿ’œ ์„œ๋กœ์—๊ฒŒ ์ข‹์•˜๋˜ ์  ํ”ผ๋“œ๋ฐฑ - Dear. Minsup - Dear. Whales ๐Ÿ‹ ----