(๐Ÿ””๋‹น๊ทผ!) ๋ฐ˜๊ฐ€์šด ์ค‘๊ณ ๊ฑฐ๋ž˜ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๋งŒ๋“ค๊ธฐ

์•ˆ๋…•ํ•˜์„ธ์š”. ์ค‘๊ณ ๊ฑฐ๋ž˜์‹ค์—์„œ iOS ์—”์ง€๋‹ˆ์–ด๋กœ ์ผํ•˜๊ณ  ์žˆ๋Š” Lychee์˜ˆ์š”.

๋‹น๊ทผ ์ค‘๊ณ ๊ฑฐ๋ž˜, ๋‹ค์–‘ํ•œ ๋ฌผ๊ฑด์„ ์‚ฌ๊ณ ํŒ” ๋•Œ ์ž์ฃผ ์ด์šฉํ•˜์‹ค ํ…๋ฐ์š”. ์ฐพ๊ณ  ์žˆ๋Š” ๋ฌผํ’ˆ์ด ์˜ฌ๋ผ์™”์„ ๋•Œ ๋ฐ”๋กœ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๊ธฐ๋Šฅ์„ ์•„์‹œ๋‚˜์š”?

์ž‘๋…„ ๊ฐ€์„ ์ฏค ๋…ธํŠธ๋ถ์ด ํ•„์š”ํ•ด์„œ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์œผ๋กœ ๋…ธํŠธ๋ถ ๊ธฐ์ข…์„ ๋“ฑ๋กํ•ด๋‘์—ˆ๋˜ ์ ์ด ์žˆ์–ด์š”. ์ œ๊ฐ€ ์ฐพ๋˜ ๊ธฐ์ข…์˜ ๊ธ€์ด ์˜ฌ๋ผ์˜ฌ ๋•Œ ๋ฐ”๋กœ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์•˜์ฃ . ๊ทธ๋Ÿฐ๋ฐ ์ข…์ข… ๋…ธํŠธ๋ถ ์ผ€์ด์Šค, ๋…ธํŠธ๋ถ ์ถฉ์ „๊ธฐ์™€ ๊ฐ™์ด ๋“ฑ๋กํ•œ ํ‚ค์›Œ๋“œ๊ฐ€ ํฌํ•จ๋œ ๋‹ค๋ฅธ ๋ฌผ๊ฑด์˜ ์•Œ๋ฆผ์„ ๋ฐ›๊ธฐ๋„ ํ–ˆ์–ด์š”. ์ด๋Ÿด ๋•Œ๋Š” ๊ธฐ๋‹ค๋ฆฌ๋˜ ์•Œ๋ฆผ์ด ์•„๋‹ˆ๋ผ์„œ ์‹ค๋งํ•˜๊ธฐ๋„ ํ–ˆ์—ˆ์–ด์š”.

๊ทธ ์ฆˆ์Œ ์ €ํฌ ํŒ€์€ ์ค‘๊ณ ๊ฑฐ๋ž˜ ๋ฆฌํ…์…˜์— ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๋Š” ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์„ ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ณด๊ธฐ ์‹œ์ž‘ํ–ˆ์–ด์š”. ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์„ ๋“ฑ๋กํ•˜๋Š” ์ง€ํ‘œ๋Š” ๊พธ์ค€ํžˆ ์„ฑ์žฅํ•˜๊ณ  ์žˆ์œผ๋‚˜, ๋ฐœ์†ก๋œ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ํ‘ธ์‹œ์˜ ์–‘์— ๋น„ํ•ด ๋‚ฎ์€ ์˜คํ”ˆ์œจ์„ ๋ณด์•˜์„ ๋•Œ ์‚ฌ์šฉ์ž๋“ค์ด ์›ํ•˜๋Š” ์•Œ๋ฆผ์„ ๋ฐ›์ง€ ๋ชปํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์—ˆ์ฃ . ๊ทธ๋ ‡๊ฒŒ ์›์น˜ ์•Š๋Š” ์•Œ๋ฆผ์œผ๋กœ ํ”ผ๋กœ๊ฐ€ ์Œ“์ด๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๋กœ ํ–ˆ์–ด์š”.

Before > ๊ธฐ์กด ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๋“ฑ๋ก ํ™”๋ฉด

ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์˜ ๋ฌธ์ œ๋ฅผ ๋” ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ณด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž์˜ ๋ชฉ์†Œ๋ฆฌ๋ฅผ ๋“ค์–ด๋ณด์•˜์–ด์š”.

๐Ÿ—ฃ๏ธ โ€œ์ œ๊ฐ€ ์ฐพ๋Š” ๋ฌผ๊ฑด์ด ์•„๋‹ˆ์—์š”. ๋“ฑ๋กํ•œ ํ‚ค์›Œ๋“œ์™€ ์ •ํ™•ํ•˜๊ฒŒ ์ผ์น˜ํ•˜๋Š” ์•Œ๋ฆผ๋งŒ ๋ฐ›๊ณ  ์‹ถ์–ด์š”โ€

๐Ÿ—ฃ๏ธ โ€œ์ œ๊ฐ€ ์ฐพ๋Š” ๋ฌผ๊ฑด์ด๋ผ๋„, ๋„ˆ๋ฌด ๋จผ ๋™๋„ค์˜ ์•Œ๋ฆผ์€ ๋ฐ›๊ณ  ์‹ถ์ง€ ์•Š์•„์š”โ€

๐Ÿ—ฃ๏ธ โ€œ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๋ฌผํ’ˆ์˜ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์„ ๋ฐ›์œผ๋ ค๋ฉด ์–ด๋–ค ํ‚ค์›Œ๋“œ๋ฅผ ๋“ฑ๋กํ•ด์•ผํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์–ด์š”โ€

๋‹ค์–‘ํ•œ ์‚ฌ๋ก€๋ฅผ ์ƒ์ƒํ•˜๊ฒŒ ๋“ค์œผ๋ฉฐ, ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์˜ ๋ฌธ์ œ๋ฅผ ๋” ๋พฐ์กฑํ•˜๊ฒŒ ์ •์˜ํ–ˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ฐœ์„ ์ ์„ ๋ฐœ๊ตดํ•ด๋‚˜๊ฐ”๊ณ  ๊ทธ๋ ‡๊ฒŒ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๊ฐœ์„  ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ–ˆ์–ด์š”. ํด๋ผ์ด์–ธํŠธ ๋ฆด๋ฆฌ์ฆˆ ๋กœ๊ทธ๋ฅผ ๋Œ์•„๋ณด๋‹ˆ ์ง€๋‚œ 5๊ฐœ์›” ๋™์•ˆ ์•„์ฃผ ๊ธด๋ฐ€ํ•˜๊ณ  ์น˜์—ดํ•˜๊ฒŒ ๋ชฐ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์„ ๋ณด๋‚ธ ๊ฒƒ ๊ฐ™์•„์š” ๐Ÿ˜„

5๊ฐœ์›” ๊ฐ„์˜ ํด๋ผ์ด์–ธํŠธ Release Log

๊ฐœ์„  ํ”„๋กœ์ ํŠธ๋Š” ํฌ๊ณ  ์ž‘์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์‹คํ—˜๊ณผ ๊ธฐ๋Šฅ ๊ฐœ์„ ์„ ๋ฐ˜๋ณตํ•˜๋Š” ์‚ฌ์ดํด๋กœ ์ง„ํ–‰๋˜์—ˆ์–ด์š”. ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๋“ฑ๋ก ๋ฐ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ ๊ฐœํŽธ๊ณผ ํ•จ๊ป˜ ๋” ์ ์ ˆํ•œ ํ‚ค์›Œ๋“œ๋ฅผ ๋“ฑ๋กํ•˜๋„๋ก ๋•๋Š” ์—ฌ๋Ÿฌ ์ถ”์ฒœ ์‹คํ—˜ ๋“ฑ์„ ๋ฐ˜๋ณตํ–ˆ์ฃ . ๊ทธ ๊ฒฐ๊ณผ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์˜คํ”ˆ์œจ์ด 2๋ฐฐ ๊ฐ€๊นŒ์ด ์ƒ์Šนํ•˜๋ฉฐ, ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์—์„œ ๊ตฌ๋งค๋ฅผ ์œ„ํ•œ ์ฑ„ํŒ…์œผ๋กœ ์ „ํ™˜ํ•˜๋Š” ์ˆ˜๋„ ํ•จ๊ป˜ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ์–ด์š”. ๐Ÿ‘๐Ÿป

์ด๋ ‡๊ฒŒ ์ œํ’ˆ์˜ ์„ฑ์žฅ์„ ์œ„ํ•ด ๋น ๋ฅด๊ฒŒ ๊ฐœ์„ ์„ ๋ฐ˜๋ณตํ•˜๋Š” ๊ณผ์ •์—์„œ, ์ €์—๊ฒŒ ํฐ ๋„์›€์ด ๋˜์—ˆ๋˜ ์œ ์—ฐํ•œ ๋ชจ๋ฐ”์ผ ์„ค๊ณ„์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆ ๋ณด๋ ค๊ณ  ํ•ด์š”!

๋…๋ฆฝ์ ์ธ ํ™˜๊ฒฝ, Feature Module ๊ธฐ๋ฐ˜์œผ๋กœ

ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ Feature Module

๋‹น๊ทผ iOS ์•ฑ์€ Feature, UI, Domain, Core, Shared์˜ 5๊ฐ€์ง€ ๊ณ„์ธต์„ ๊ฐ€์ง„ ๋ชจ๋“ˆ๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋Š”๋ฐ์š”. ์ƒˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค Feature Module์„ ์ถ”๊ฐ€ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ๋ถ„๋ฆฌ๋  ์ˆ˜ ์žˆ๋Š” ๋งฅ๋ฝ์˜ ๊ธฐ๋Šฅ์ด๋ผ๋ฉด ๋ณ„๋„์˜ Feature Module์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์–ด์š”. (๋‹น๊ทผ iOS์ฑ•ํ„ฐ์˜ ๋ชจ๋“ˆํ™”์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ๊ธ€์„ ์ฐธ๊ณ ํ•ด์ฃผ์…”๋„ ์ข‹์•„์š”.)

โ€œ์ƒˆ ์ˆ ์€ ์ƒˆ ๋ถ€๋Œ€์—โ€ ๋ผ๋Š” ๊ฒฉ์–ธ์— ๋”ฐ๋ผ ์ƒˆ๋กœ ๊ฐœ์„ ๋˜๋Š” ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๊ธฐ๋Šฅ์„ ๋‹ด์„ ๋ณ„๋„์˜ Feature Module์„ ์ƒ์„ฑํ–ˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  ์ƒˆ ๋ชจ๋“ˆ ์œ„์— ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์—์„œ ์‚ฌ์šฉํ•  ์†Œ์Šค์ฝ”๋“œ๋“ค์„ ์„ค๊ณ„ํ•ด ์Œ“์•„์˜ฌ๋ ธ์–ด์š”.

FleaMarketKeywordNotificationFeature ๋ชจ๋“ˆ์€ ๋‹ค๋ฅธ Feature ๋ชจ๋“ˆ๊ณผ ์•ฑ ํƒ€๊ฒŸ๊ณผ๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ๋ถ„๋ฆฌ๊ฐ€ ๋˜์–ด์žˆ์–ด์„œ, ์ƒˆ ๊ธฐ๋Šฅ์„ ๋ผ์›Œ๋„ฃ์„ ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋กœ๋ถ€ํ„ฐ ๋น„๊ต์  ์•ˆ์ „ํ•œ ํ™˜๊ฒฝ์ด์—ˆ์–ด์š”. ๋•๋ถ„์— ์ ์€ ๋ถ€๋‹ด๊ฐ์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ž‘์—…์„ ํ•ด๋‚˜๊ฐˆ ์ˆ˜๊ฐ€ ์žˆ์—ˆ์ง€์š”. ๋˜ ์ „์ฒด ๋ชจ๋“ˆ์„ ๋นŒ๋“œํ•˜์ง€ ์•Š๊ณ ๋„ ๋‹จ๋… ๋ชจ๋“ˆ์—์„œ ๋นŒ๋“œ์™€ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ์— ์ด์ „๋ณด๋‹ค ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ƒ์‚ฐ์„ฑ๋„ ๋Œ์–ด์˜ฌ๋ฆด ์ˆ˜ ์žˆ์—ˆ์–ด์š”.

์ดˆ๊ธฐ๋ถ€ํ„ฐ ๋ณ€ํ™”์— ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ

ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๊ฐœ์„ ์˜ ์ฒซ ๊ณผ์ œ๋กœ, ๊ฐ€์žฅ ๋งŽ์€ ๋ถˆํŽธ์‚ฌํ•ญ์œผ๋กœ ๊ผฝํ˜”๋˜ โ€œ๋ถˆํ•„์š”ํ•œ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผโ€์„ ์ค„์ด๊ธฐ ์œ„ํ•œ ํ‚ค์›Œ๋“œ์˜ ์กฐ๊ฑด์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜์—ˆ์–ด์š”. ๊ธฐ์กด์—๋Š” ํ‚ค์›Œ๋“œ๋งŒ์„ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ์š”, ์ด์ œ ๋“ฑ๋กํ•œ ํ‚ค์›Œ๋“œ์˜ ์นดํ…Œ๊ณ ๋ฆฌ, ๊ฐ€๊ฒฉ ๋ฒ”์œ„, ์ œ์™ธํ•˜๊ณ  ์‹ถ์€ ํ‚ค์›Œ๋“œ์™€ ๊ฐ™์€ ์กฐ๊ฑด์„ ์„ค์ •ํ•ด์„œ ํ•„์š”ํ•œ ์•Œ๋ฆผ๋งŒ ํ•„ํ„ฐ๋งํ•ด์„œ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•œ ๊ฒƒ์ด์ฃ .

After > ํ‚ค์›Œ๋“œ์˜ ์กฐ๊ฑด์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ ์ƒˆ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์„ค์ •ํ™”๋ฉด

์ƒˆ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์„ค์ •ํ™”๋ฉด UI์˜ ์ดˆ๊ธฐ ์ŠคํŽ™์€ ๋‹จ์ผ ์„ธ๋กœํ˜• ๋ชฉ๋ก์œผ๋กœ ๊ตฌ์„ฑ๋˜์—ˆ์–ด์š”. (์™ผ์ชฝ ์ด๋ฏธ์ง€ ์ฐธ๊ณ ) ํ•˜์ง€๋งŒ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ ๋ถˆํŽธํ•จ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๊ตฌ์กฐ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํ˜•ํƒœ๋กœ ๋ณ€ํ™”๋  ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด๋‘์–ด์•ผ ํ–ˆ์ฃ . ๊ทธ๋ž˜์„œ ์ฒ˜์Œ์—” ๋น„๋ก Verticle List์˜ ๋‹จ์ˆœํ•œ ํ˜•ํƒœ์ด์ง€๋งŒ enum์œผ๋กœ Section ํƒ€์ž…์„ ์ •์˜ํ–ˆ๊ณ , ์ด์— ๋”ฐ๋ผ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋„๋ก ํ–ˆ์–ด์š”.

๋ฆฌ์ŠคํŠธ UI๋Š” KarrotListKit์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์„ฑํ–ˆ๋Š”๋ฐ์š”. List, Section, Cell์„ ์ง๊ด€์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ์šฉ์ดํ–ˆ์–ด์š”. ๋˜ ๊ฐ ์ปดํฌ๋„ŒํŠธ์— modifier๋ฅผ ๋ถ™์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ ˆ์ด์•„์›ƒ ์†์„ฑ์„ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ์ปดํฌ๋„ŒํŠธ์— ๋ฐœ์ƒํ•˜๋Š” ์•ก์…˜์„ ๋ฐ›๋„๋ก ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด์„œ UI ๊ตฌ์„ฑ ๋‹จ๊ณ„์˜ ์ƒ์‚ฐ์„ฑ์„ ์˜ฌ๋ ค์ฃผ์—ˆ์–ด์š”.

enum Section: Equatable, Identifiable {
case registeredUserKeywordList([ItemViewModel])
}

func updateSection(section: Section) {
collectionViewAdapter.apply(
List {
sections.map { section -> Section in
switch section {
case .registeredUserKeywordList(let viewModels):
return Section(
id: id,
cells: makeRegisteredKeywordSectionItems(
viewModels: viewModels
)
)
.withSectionLayout(.vertical(spacing: 0.0))
}
}
}
)
}

๋ฆฌ๋‰ด์–ผ๋œ ์„ธ๋กœํ˜• ๋ฆฌ์ŠคํŠธ์˜ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์„ค์ •ํ™”๋ฉด์„ ๋ฐฐํฌ ํ›„, ๋‹ค์Œ ์ž‘์—…์œผ๋กœ ํ‚ค์›Œ๋“œ ๋“ฑ๋ก์„ ์ œ์•ˆํ•˜๋Š” ์‹คํ—˜์„ ํ•˜๊ธฐ๋กœ ํ–ˆ์–ด์š”. ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์„ค์ • ํ™”๋ฉด์— ๋ฐฉ๋ฌธํ–ˆ์„ ๋•Œ ์–ด๋–ค ํ‚ค์›Œ๋“œ๋ฅผ ๋“ฑ๋กํ•ด์•ผํ•  ์ง€ ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ์„ ๊ฒƒ์ด๋ผ๋Š” ๊ฐ€์„ค์ด์—ˆ์ฃ . ๊ทธ๋ ‡๊ฒŒ ์ตœ๊ทผ ๋ณธ ๊ฒŒ์‹œ๊ธ€์„ ํ† ๋Œ€๋กœ ์ถ”์ฒœ๋œ ํ‚ค์›Œ๋“œ ์นฉ ๋ชฉ๋ก์„ ๊ธฐ์กด ๋ฆฌ์ŠคํŠธ ํ•˜๋‹จ์— ๋ณด์—ฌ์ฃผ๋Š” ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์–ด์š”.

์ตœ๊ทผ ๋ณธ ๊ฒŒ์‹œ๊ธ€์„ ํ† ๋Œ€๋กœ ํ‚ค์›Œ๋“œ ๋“ฑ๋ก์„ ์ œ์•ˆํ•˜๋Š” ์‹คํ—˜ UI

์ง€๋‚œ ์ž‘์—…์—์„œ ๋ฆฌ์ŠคํŠธ์— ์–ด๋–ค ์„น์…˜์ด ์ถ”๊ฐ€๋˜์–ด๋„ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•œ ๋•๋ถ„์— ์ƒˆ case๋ฅผ ์ •์˜ํ•˜๊ณ , ์—ฐ๊ฒฐํ•˜๋Š” ์ž‘์€ ๋ณ€๊ฒฝ๋งŒ์œผ๋กœ ์‹คํ—˜์„ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์—ˆ์–ด์š”. Section ์— recommendedKeywordList์˜ case๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ํ•ด๋‹น ์„น์…˜์— ๋“ค์–ด๊ฐˆ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ์„ฑํ•ด ์—ฐ๊ฒฐํ•ด์ฃผ์—ˆ์–ด์š”.

enum Section: Equatable, Identifiable {
case registeredUserKeywordList([ItemViewModel])
case recommendedKeywordList(RecommendedViewModel)
}

๋ฏธ๋ž˜์— ๋Œ€ํ•ด 100% ์˜ˆ์ธกํ•  ์ˆ˜๋Š” ์—†๊ฒ ์ง€๋งŒ, ํŒ€์›๋“ค๊ณผ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆ„์—ˆ๋˜ ๊ฒƒ์„ ํ† ๋Œ€๋กœ ์˜ˆ์ƒ๋˜๋Š” ๋ณ€๊ฒฝ์ ์„ ์œ ์—ฐํ•˜๊ฒŒ ์„ค๊ณ„ํ•ด ๋‘” ๊ฒƒ์ด ๋„์›€์ด ๋˜์—ˆ์–ด์š”.

N๊ฐœ์˜ ๊ตญ๊ฐ€, ํ•˜๋‚˜์˜ ํ™”๋ฉด

ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ๊ธฐ๋Šฅ์€ ๊ตญ๋‚ด๋ฅผ ๋น„๋กฏํ•ด ๋ถ๋ฏธ, ์ผ๋ณธ, ์˜๊ตญ์—์„œ๋„ ๋™์ผํ•˜๊ฒŒ ์ œ๊ณต๋˜๊ณ  ์žˆ์–ด์š”. ์ค‘๊ณ ๊ฑฐ๋ž˜๋ฅผ ์ด์šฉํ•  ๋•Œ ํ•„์š”ํ•œ ๋ฌผ๊ฑด์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›๊ณ  ์‹ถ์€ ๋‹ˆ์ฆˆ๋Š” ์–ด๋””์„œ๋‚˜ ๋™์ผํ–ˆ๊ธฐ์— ์ „ ๊ตญ๊ฐ€๋ฅผ ํ•จ๊ป˜ ๊ฐœ์„ ํ•˜๊ณ ์ž ํ–ˆ์–ด์š”.

์ „ ๊ตญ๊ฐ€์— ์ œ๊ณต๋˜๋Š” ๊ธฐ๋Šฅ์ผ ๋•Œ๋Š” ๋น„์Šทํ•œ UI๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์ƒํ™ฉ์—๋„ ๊ตญ๊ฐ€๋ณ„ UX์˜ ์œ ์—ฐํ•จ์„ ์œ„ํ•ด View๋ฅผ ๋”ฐ๋กœ ๊ฐ€์ ธ๊ฐ€๊ฑฐ๋‚˜, ViewModelFactory ๊ตฌํ˜„์ฒด๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค๊ธฐ๋„ ํ–ˆ์—ˆ๋Š”๋ฐ์š”. ์ €ํฌ ํŒ€์€ ์ด์— ๋Œ€ํ•ด ๊ตญ๊ฐ€ ๋ถ„๊ธฐ๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ณ  ๊ณตํ†ตํ™”ํ•˜์ž๋Š” ์˜๊ฒฌ์ด์—ˆ์–ด์š”.

๊ตญ๊ฐ€๋ณ„๋กœ ํŠน์ˆ˜์„ฑ์„ ๊ฐ€์ ธ๊ฐ€๋ฉด ๊ด€๋ฆฌ๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ  ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ์ž˜ ์•Œ์ง€ ๋ชปํ•˜๋Š” ์ž‘์—…์ž๊ฐ€ ์ถ”๊ฐ€ ์ž‘์—…์„ ํ•  ๋•Œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ์˜ ์œ„ํ—˜๋„๊ฐ€ ๋†’์•„์ง€๊ธฐ ๋•Œ๋ฌธ์ด์—์š”. ์ €ํฌ ํŒ€ ํ”„๋กœ๋•ํŠธ ๋””์ž์ด๋„ˆ Bada๊ฐ€ ๋จธ๋ฆฌ๋ฅผ ์‹ธ๋งค์‹œ๋ฉฐ ๊ตญ๊ฐ€๋ณ„๋กœ ์ตœ๋Œ€ํ•œ ๋™์ผํ•œ UI/UX๋ฅผ ์„ค๊ณ„ํ•ด์ฃผ์‹  ๋•์— ํด๋ผ์ด์–ธํŠธ์—์„œ๋„ ๊ตญ๊ฐ€๋ถ„๊ธฐ ์—†์ด ํ•˜๋‚˜์˜ Presentation Layer๋กœ ํ™”๋ฉด์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์—ˆ์–ด์š”.

๋‹จ์ˆœํ•ด์ง„ Presentation Layer

ํ•˜์ง€๋งŒ, ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์„ ๋ฐ›์„ ๋™๋„ค ๋ฒ”์œ„๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๋ฉฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์–ด์š”. ๊ตญ๊ฐ€๋ณ„๋กœ ์ ์šฉ๋˜๋Š” ์ง€์—ญ ์‹œ์Šคํ…œ์ด ๋‹ฌ๋ž๊ณ , ์ด์— ๋”ฐ๋ผ์„œ ๊ฐ๊ฐ ๋‹ค๋ฅธ UI๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ๋ฐ–์— ์—†์—ˆ์–ด์š”.

  • ํ•œ๊ตญ : ๋ฐ˜๊ฒฝ์— ์žˆ๋Š” ๋™๋„ค์˜ ๊ฐœ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ 4๋‹จ๊ณ„์˜ Step Slider UI ์ œ๊ณต
  • ์บ๋‚˜๋‹ค : ๋ฐ˜๊ฒฝ km ๋ฒ”์œ„๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ 5๋‹จ๊ณ„์˜ Slider UI ์ œ๊ณต
  • ๋ฏธ๊ตญ : ๋ฐ˜๊ฒฝ mi ๋ฒ”์œ„๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ 5๋‹จ๊ณ„์˜ Slider UI ์ œ๊ณต
  • ์ผ๋ณธ : ๋ฐ˜๊ฒฝ์— ์žˆ๋Š” ๋™๋„ค์˜ ๊ฐœ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ 4๋‹จ๊ณ„์˜ Slider UI ์ œ๊ณต
ํ•œ๊ตญ, ๋ถ๋ฏธ, ์ผ๋ณธ์˜ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์„ ๋ฐ›์„ ๋™๋„ค๋ฒ”์œ„ ์„ค์ • UI

์ง€์—ญ ์‹œ์Šคํ…œ์— ๋”ฐ๋ผ ์„œ๋ฒ„์˜ EndPoint์™€ Response DTO๋Š” ๋‹ค๋ฅด์ง€๋งŒ, ํ™”๋ฉด์—์„œ ๋‹ค๋ค„์ง€๋Š” ์š”์†Œ๋Š” ๋‹ค๋ฅด์ง€ ์•Š์•˜์–ด์š”. ๊ฐ ๊ตญ๊ฐ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋™๋„ค ๋ฒ”์œ„์™€, ๊ฐ ๋™๋„ค ๋ฒ”์œ„๊ฐ€ ์–ด๋Š ์ •๋„์˜ ๋ฒ”์œ„์ธ์ง€ ํ‘œํ˜„(๋™๋„ค์˜ ๊ฐœ์ˆ˜ OR ๋ฒ”์œ„์˜ ํฌ๊ธฐ)ํ•˜๋Š” ๊ฒƒ์€ ๋™์ผํ•˜๋‹ค๋Š” ์ ์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ํ•˜๋‚˜์˜ KeywordNotificationTownData ๋ฅผ ์„ค๊ณ„ํ–ˆ์–ด์š”.

struct KeywordNotificationTownData {
let town: KeywordNotificationTown
var metadata: KeywordNotificationTown.Metadata
}

enum KeywordNotificationTown {
case fooLocationSystem(FooLocation)
case barLocationSystem(BarLocation)

public var id: Int {
switch self {
case .fooLocationSystem(let fooLocation):
return fooLocation.id
case .barLocationSystem(let barLocation):
return barLocation.h3Index
}
}

public var name: String {
switch self {
case .fooLocationSystem(let fooLocation):
return fooLocation.name
case .barLocationSystem(let barLocation):
return barLocation.name
}
}

public var coordinate: KarrotLocationCoordinate? {
switch self {
case .fooLocationSystem(let fooLocation):
return fooLocation.coordinate
case .barLocationSystem(let barLocation):
return barLocation.coordinate
}
}

struct Metadata: Then {
var currentRange: KeywordNotificationTown.Range
var defaultRange: KeywordNotificationTown.Range
var rangeInfos: [KeywordNotificationTown.RangeInfo]
}
}

๊ทธ๋ฆฌ๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” Interactor์— ๊ตญ๊ฐ€์— ๋”ฐ๋ผ ๊ฐ ์ง€์—ญ ์‹œ์Šคํ…œ์˜ EndPoint์—์„œ ์ง€์—ญ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€ KeywordNotificationTown๋กœ ๋งตํ•‘ํ•ด ๋‚ด๋ ค์ฃผ๋Š” Broker๋ฅผ ๋‘์—ˆ์–ด์š”. Broker์—๊ฒŒ fetch๋ฅผ ์š”์ฒญํ•˜๋ฉด, Interactor์—์„œ๋Š” ์–ด๋Š ๊ตญ๊ฐ€์ธ์ง€ ์•Œ ํ•„์š” ์—†์ด, KeywordNotificationTownData ํƒ€์ž…์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›์•„ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•  ๋ฐ์ดํ„ฐ๋ฅผ Presenter์— ์ „๋‹ฌํ•ด์š”.

์ „ ๊ตญ๊ฐ€์— ํ•œ ๋ฒŒ๋กœ ์ œ๊ณต๋˜๋Š” View์™€ ViewModelFactory

ํ•˜๋‚˜์˜ ํƒ€์ž…์ด๋‹ค ๋ณด๋‹ˆ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•˜๋‚˜์˜ View์™€ ViewModel, ViewModelFactory๋กœ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ์–ด์š”. ๋•๋ถ„์— Presentation Layer์—์„œ์˜ ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์ฃ . (์ด ๊ณผ์ •์—์„œ ํ•จ๊ป˜ ๊ณ ๋ฏผํ•ด์ฃผ์‹  Elon.park์—๊ฒŒ ๊ฐ์‚ฌ์ธ์‚ฌ๋ฅผ ์ „ํ•ด์š”.)

๋ฐ€๋„์žˆ๋Š” ํ…Œ์ŠคํŠธ

๋น ๋ฅด๊ฒŒ ์‚ฌ์ดํด์„ ๋Œ๋ฉฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ๋„ ์ƒ๊ฒผ์–ด์š”. ์ €๋Š” ์ด์ œ๊นŒ์ง€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋ถ€ํ„ฐ ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๋กœ์ง, ๋ผ์šฐํŒ… ๋กœ์ง, ํ–‰๋™ ๋ฐ์ดํ„ฐ ์ „์†ก ๋กœ์ง๊นŒ์ง€ ๋Œ€๋ถ€๋ถ„์˜ ๋กœ์ง์— ๋Œ€ํ•ด ์œ ๋‹›ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์™”์–ด์š”. ๋‹จ์ˆœ by-pass ๋˜๋Š” ๊ฐ’์„ mock ๊ฐ์ฒด์— ์ „๋‹ฌํ•ด ํ˜ธ์ถœ ํšŸ์ˆ˜๋ฅผ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋Š” ๋ถˆํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ๋„ ๋งŽ์•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด์š”.

๋” ํšจ์œจ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์—ˆ๋˜ ์ €๋Š” ์ด๋Ÿฐ ๊ณ ๋ฏผ๋“ค์„ ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์–ด์š”.

  • ์ฃผ์š” ์œ ์ฆˆ์ผ€์ด์Šค๋งŒ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–จ๊นŒ
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์–ผ๋งˆ๋‚˜ ์ด˜์ด˜ํ•˜๊ฒŒ ๊ฒ€์ฆํ•ด์•ผํ• ๊นŒ
  • ๋‹จ์ˆœํ•œ ๋ผ์šฐํŒ…, ๋กœ๊น… ๋กœ์ง์€ ์œ ๋‹›ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ๋ณด๋‹ค ๊ตฌ๋™ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋Š”๊ฒŒ ์–ด๋–จ๊นŒ
  • โ€ฆ ๋“ฑ๋“ฑ

์—ฌ๋Ÿฌ ๊ณ ๋ฏผ ๋์—, ์ฃผ์š” ์œ ์ฆˆ์ผ€์ด์Šค์— ๋Œ€ํ•œ ์•ก์…˜๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์œ„์ฃผ๋กœ ๋ฐ€๋„์žˆ๊ฒŒ ์œ ๋‹›ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ์–ด์š”. ์œ ๋‹› ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์— ๋Œ€ํ•œ ๋ถ€๋‹ด๊ฐ์„ ๋‚ฎ์ถ”๋˜, ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ์ œ๋Œ€๋กœ ๊ฒ€์ฆํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผํ• ์ง€ ๊ณ ๋ฏผํ•˜๋ฉฐ ์ž‘์„ฑํ–ˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  ๊ตฌ๋™ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋Š” ์‹œ๊ฐ„์„ ๋” ๋Š˜๋ฆฌ๋ฉฐ ์ œํ’ˆ์„ ๋งŽ์ด ์จ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ์š”. ๊ทธ ๊ณผ์ •์—์„œ ๊ฒฝํ—˜์ ์ธ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ์–ด์ƒ‰ํ•จ์„ ๋ฐœ๊ฒฌํ•ด ์ถœ์‹œ ์ „์— ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ์ ๋„ ๊ธฐ์–ต์— ๋‚จ์•„์š”.

๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ํ™”๋ฉด์—์„œ ํ˜„์žฌ ๊ฒ€์ƒ‰ํ•œ ํ‚ค์›Œ๋“œ๋ฅผ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์œผ๋กœ ๋“ฑ๋กํ•˜๋ฉด, ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์กฐ๊ฑด ์„ค์ •์„ ํ•ด๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์•ˆ๋‚ด๋ฅผ ํ•ด์ฃผ๋Š” ์˜จ๋ณด๋”ฉ ๊ธฐ๋Šฅ์ด ์žˆ์—ˆ์–ด์š”.

์ด๋ฅผ ํ†ตํ•ด ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์กฐ๊ฑด ์„ค์ • ํ™”๋ฉด์— ์ง„์ž…ํ•˜์—ฌ ์นดํ…Œ๊ณ ๋ฆฌ, ๊ฐ€๊ฒฉ ๋“ฑ์˜ ์กฐ๊ฑด ์„ค์ •์„ ์™„๋ฃŒํ•˜๊ณ  ๋‚˜์˜จ ๊ฒฝ์šฐ์— ๋ฐ”๋กœ ์ด์ „์— ์žˆ๋˜ ๊ฒ€์ƒ‰ํ™”๋ฉด์œผ๋กœ ๋Œ์•„์˜ค๊ฒŒ ๋˜๋Š”๋ฐ์š”. ์กฐ๊ฑด์„ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ๊ฑฐ๋‚˜ ๋‹ค์‹œ ์กฐ๊ฑด์„ ๋ณด๊ณ  ์‹ถ์„ ๋•Œ๋Š” ๋งฅ๋ฝ์ด ์ด์–ด์งˆ ๊ฒฝ๋กœ๊ฐ€ ๋ถ€์žฌํ•˜๋‹ค๋Š” ๊ฒƒ์ด ์•„์‰ฌ์› ์–ด์š”. ๊ทธ๋ž˜์„œ ์™„๋ฃŒ ํ›„ ์Šค๋‚ต๋ฐ”์— ๋ณด๋Ÿฌ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ๋„ฃ์–ด ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ ์กฐ๊ฑด ์„ค์ • ํ™”๋ฉด์œผ๋กœ ๋‹ค์‹œ ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ์ž…๊ตฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜์—ˆ์–ด์š”.

์œ ๋‹› ํ…Œ์ŠคํŠธ๋„ ๋ฌผ๋ก  ์ค‘์š”ํ•˜์ง€๋งŒ, ํด๋ผ์ด์–ธํŠธ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๊ฐœ๋ฐœํ•œ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ๋งŽ์ด ์จ๋ณด๋ฉด์„œ ํ™”๋ฉด ๋„ˆ๋จธ์˜ ๋ถ€๋ถ„๊นŒ์ง€ ๊ฒ€์ฆํ•ด๋ณด๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฑธ ๋ฐฐ์› ์–ด์š”.

๊ทธ๋ ‡๊ฒŒ 5๊ฐœ์›” ๊ฐ„ ๊ฐœ์„ ์„ ๋ฐ˜๋ณตํ•œ ๋์— ์šฐ๋ฆฌ ํ‚ค์•Œ์ด๊ฐ€ ๋‹ฌ๋ผ์กŒ์–ด์š”! ์•„์ง ๋‹น๊ทผ์—์„œ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์„ ์จ๋ณด์‹  ์ ์ด ์—†๋‹ค๋ฉด ํ•„์š”ํ•œ ๋ฌผํ’ˆ์ด ์žˆ์„ ๋•Œ ํ•œ ๋ฒˆ ์จ๋ณด์‹œ๊ธธ ์ž์‹ ์žˆ๊ฒŒ ์ถ”์ฒœ๋“œ๋ ค์š” ๐Ÿ˜

๊ฐœ์„  ์ดํ›„ ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์˜ ๋“ฑ๋ก ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•˜๋ฉฐ ์•Œ๋ฆผ ์˜คํ”ˆ์œจ๋„ ํ•จ๊ป˜ ๋Š˜์–ด๋‚ฌ๊ณ , ์ด์ „์— ๋น„ํ•ด ๋ถˆํ•„์š”ํ•œ ์•Œ๋ฆผ์— ๋Œ€ํ•œ ๋ฌธ์˜๋„ ๋ˆˆ์— ๋„๊ฒŒ ์ค„์—ˆ์–ด์š”. ํ‚ค์›Œ๋“œ ์•Œ๋ฆผ์—์„œ ์ด์–ด์ง€๋Š” ์ค‘๊ณ ๊ฑฐ๋ž˜ ์ฑ„ํŒ… ์ „ํ™˜์œจ ์ƒ์Šน๊นŒ์ง€ ๊ฑด๊ฐ•ํ•˜๊ฒŒ ์ž˜ ์ด์–ด์ ธ์„œ ๋” ์˜๋ฏธ์žˆ๋Š” ๊ฒฐ๊ณผ์˜€๋˜ ๊ฒƒ ๊ฐ™์•„์š” ๐Ÿ‘๐Ÿป

์ด ๊ธ€์„ ํ†ตํ•ด ํ•จ๊ป˜ ์น˜์—ดํ•˜๊ฒŒ ๋‹ฌ๋ ธ๋˜ ์šฐ๋ฆฌ ํŒ€์›๋“ค.. ์ •๋ฆฌ์ฒœ์žฌ์— ๋ฐ์ดํ„ฐ๊นŒ์ง€ ์ž˜ ๋ณด๋Š” PM Suzy, ์ฐจ๋ถ„ํ•˜๊ฒŒ ์šฐ๋ฆฌ ํŒ€์˜ ๋„˜์น˜๋Š” ์•„์ด๋””์–ด์™€ ์—ด์ •์„ ์ •๋ฆฌํ•ด ๋ฉ‹์ง€๊ฒŒ ๋‹ด์•„์ฃผ๋Š” ํ”„๋กœ๋•ํŠธ ๋””์ž์ด๋„ˆ Bada, ์šฐ์ฃผ๋ฅผ ์‚ฌ๋ž‘ํ•˜๋Š” ๊ฑด๊ฐ•ํ•œ Rails ์„œ๋ฒ„ ์—”์ง€๋‹ˆ์–ด Astro, ๋ง์€ ๋งŽ์ง€๋งŒ ํ•„์š”ํ•œ ๋ง๋งŒ ํ•˜๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ์—”์ง€๋‹ˆ์–ด Reddy์—๊ฒŒ ๊ฐ์‚ฌ์˜ ์ธ์‚ฌ๋ฅผ ์ „ํ•ด์š”๐Ÿงก

--

--