์ธํ”„๋Ÿฐ ์˜๋ฌธ ๋ธŒ๋žœ๋“œ ๋กœ๊ณ 
์ธํ”„๋Ÿฐ ์˜๋ฌธ ๋ธŒ๋žœ๋“œ ๋กœ๊ณ 

iOS Clean Architecture & MVVM: RxSwift ์™„์ „ ์ •๋ณต

Clean Architecture์™€ MVVM ํŒจํ„ด์„ ์‹ค๋ฌด์—์„œ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๋ช…ํ•˜๋ฉฐ, RxSwift, Concurrency ๋“ฑ ํ•„์ˆ˜ ๊ธฐ์ˆ ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

Thumbnail

์ดˆ๊ธ‰์ž๋ฅผ ์œ„ํ•ด ์ค€๋น„ํ•œ
[๋ชจ๋ฐ”์ผ ์•ฑ ๊ฐœ๋ฐœ, iOS] ๊ฐ•์˜์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๊ฑธ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์–ด์š”

  • Clean Architecture

  • Swift

  • MVVM

  • ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  • RxSwift

  • Alamofire

  • CoreData

  • XCText

  • Snapkit

  • Async Await

iOS Clean Architecture & MVVM: RxSwift ์™„์ „ ์ •๋ณต

ํ˜„์—…์—์„œ Clean Architecture์™€ MVVM ํŒจํ„ด์€ ์ด๋ฏธ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์œผ๋ฉฐ, ๋งŽ์€ ์ฑ„์šฉ ๊ณต๊ณ ์—์„œ๋„ ํ•„์ˆ˜ ์—ญ๋Ÿ‰์œผ๋กœ ์š”๊ตฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ•์˜๋Š” Clean Architecture์™€ MVVM์ด ๋ฌด์—‡์ธ์ง€, ์™œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ด๋ก ์ ์ธ ์„ค๋ช…๊ณผ ํ•จ๊ป˜, ์‹ค์ œ๋กœ ๊ตฌ์ฒด์ ์ธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๊ณผ ํŒจํ„ด์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, RxSwift, Concurrency, CoreData, SnapKit, Alamofire ๋“ฑ ํ˜„๋Œ€ iOS ๊ฐœ๋ฐœ์—์„œ ํ•„์ˆ˜์ ์ธ ๊ธฐ์ˆ ๋“ค์˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๊นŒ์ง€ ํ•จ๊ป˜ ๋‹ค๋ฃจ๋ฉฐ, ์‹ค๋ฌด์—์„œ ๋ฐ”๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ญ๋Ÿ‰์„ ํ‚ค์šธ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๋‚ด์šฉ์„ ๋ฐฐ์›Œ์š”

1โƒฃ ํด๋ฆฐ ์•„ํ‚คํ…์ณ ์™„๋ฒฝ ์ดํ•ด

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

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

2โƒฃ ์ถ”๊ฐ€๋กœ ๋ฐฐ์šธ์ˆ˜ ์žˆ๋Š” ๋‚ด์šฉ 

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

์ถ”๊ฐ€์ ์œผ๋กœ, ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ์œ„ํ•œ CoreData์˜ ํ™œ์šฉ๋ฒ•์„ ์†Œ๊ฐœํ•˜๋ฉฐ, XCTest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์‹ค์Šต์„ ํฌํ•จํ•ด ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ•™์Šต์ž๋Š” ์‹ค์ „์— ๋ฐ”๋กœ ์ ์šฉ ๊ฐ€๋Šฅํ•œ ๋„คํŠธ์›Œํฌ ๋ชจ๋“ˆ์„ ๊ตฌ์ถ•ํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์Šคํ‚ฌ์„ ์ตํžˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

3โƒฃ MVVM ํŒจํ„ด ์ดํ•ด

์ด ๊ฐ•์˜์—์„œ๋Š” MVVM ํŒจํ„ด์—์„œ ViewController์™€ ViewModel์ด ์–ด๋–ป๊ฒŒ ์—ญํ• ์„ ๋‚˜๋ˆ„๊ณ  ๊ฐ๊ฐ ๊ตฌํ˜„๋˜๋Š”์ง€์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. MVVM ํŒจํ„ด์— ๋Œ€ํ•œ ์ด๋ก ์ ์ธ ์ดํ•ด๋ถ€ํ„ฐ, ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊นŒ์ง€ ์ „๋ฐ˜์ ์ธ ๋‚ด์šฉ์„ ๋‹ด์•„ ํ•™์Šต์ž๊ฐ€ ์‰ฝ๊ฒŒ ๋”ฐ๋ผ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

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

4โƒฃ RxSwift, Alamofire, SnapKit ์ ๊ทน ํ™œ์šฉ

์ด ๊ฐ•์˜์—์„œ๋Š” Alamofire, SnapKit, RxSwift์™€ ๊ฐ™์€ ํ˜„์—…์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ ๊ทน ํ™œ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. Alamofire๋ฅผ ์‚ฌ์šฉํ•œ ๋„คํŠธ์›Œํฌ ํ†ต์‹  ๊ตฌํ˜„ ๋ฐฉ๋ฒ•, SnapKit์„ ํ™œ์šฉํ•œ ๋‹ค์–‘ํ•œ ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ ๋ฐฉ์‹, ๊ทธ๋ฆฌ๊ณ  RxSwift๋ฅผ ํ™œ์šฉํ•ด ViewController์™€ ViewModel ๊ฐ„์˜ ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ตฌ์ฒด์ ์œผ๋กœ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

์ด ๊ฐ•์˜๋ฅผ ํ†ตํ•ด, ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ์ด๋Ÿฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์–ด๋–ป๊ฒŒ ์‘์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ฐฐ์›Œ ๋” ํšจ์œจ์ ์ด๊ณ  ๋ฐ˜์‘์„ฑ ๋†’์€ iOS ์•ฑ์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜๊ฐ• ์ „ ์ฐธ๊ณ  ์‚ฌํ•ญ

์„ ์ˆ˜ ์ง€์‹ ๋ฐ ์œ ์˜์‚ฌํ•ญ

  • Swift ์˜ ๊ธฐ๋ณธ์ ์ธ ์ง€์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


  • ๋ฌด๋‹จ ๋ฐฐํฌ ๋ฐ ๋ณต์ œ๋ฅผ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค. ํ•™์Šต ์ž๋ฃŒ ์—ญ์‹œ ์ €์ž‘๊ถŒ์ด ์žˆ์œผ๋ฉฐ, ๊ฐœ์ธ์ ์ธ ํ•™์Šต ๋ชฉ์  ์™ธ ์‚ฌ์šฉ์„ ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ํ…œํ”Œ๋ฆฟ์€ 'AWS DeepRacer๋กœ ๋ฐฐ์šฐ๋Š” ์ธ๊ณต์ง€๋Šฅ๊ณผ ์ž์œจ์ฃผํ–‰' ๊ฐ•์˜๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๋ถ„๋“ค๊ป˜
์ถ”์ฒœ๋“œ๋ ค์š”!

ํ•™์Šต ๋Œ€์ƒ์€
๋ˆ„๊ตฌ์ผ๊นŒ์š”?

  • Clean Architecture์™€ MVVM ํŒจํ„ด์„ ์ดํ•ดํ•˜๊ณ  ์‹ถ์€ ๊ฐœ๋ฐœ์ž

  • iOS ์•ฑ ๊ฐœ๋ฐœ์˜ ๊ธฐ๋ณธ๊ธฐ๋ฅผ ๋‹ค์ง€๊ณ  ์‹ถ์€ ์ดˆยท์ค‘๊ธ‰ ๊ฐœ๋ฐœ์ž

์„ ์ˆ˜ ์ง€์‹,
ํ•„์š”ํ• ๊นŒ์š”?

  • Swift

  • UIKit

์•ˆ๋…•ํ•˜์„ธ์š”
๋ค๋ฒจ๋กœํผ์ž…๋‹ˆ๋‹ค.

317

๋ช…

์ˆ˜๊ฐ•์ƒ

13

๊ฐœ

์ˆ˜๊ฐ•ํ‰

23

๊ฐœ

๋‹ต๋ณ€

4.7

์ 

๊ฐ•์˜ ํ‰์ 

3

๊ฐœ

๊ฐ•์˜

6๋…„์ฐจ iOS ๊ฐœ๋ฐœ์ž ๋ค๋ฒจ๋กœํผ์ž…๋‹ˆ๋‹ค

ํ˜„์—…์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๋Š” ๊ฐ•์˜

์ดˆ์ค‘๊ธ‰ ๋ ˆ๋ฒจ์—๊ฒŒ ํ•„์š”ํ•œ ๊ฐ•์˜๋ฅผ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค

 

 

๋”๋ณด๊ธฐ

์ปค๋ฆฌํ˜๋Ÿผ

์ „์ฒด

29๊ฐœ โˆ™ (5์‹œ๊ฐ„ 31๋ถ„)

ํ•ด๋‹น ๊ฐ•์˜์—์„œ ์ œ๊ณต:

์ˆ˜์—…์ž๋ฃŒ
๊ฐ•์˜ ๊ฒŒ์‹œ์ผ: 
๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ์ผ: 

์ˆ˜๊ฐ•ํ‰

์•„์ง ์ถฉ๋ถ„ํ•œ ํ‰๊ฐ€๋ฅผ ๋ฐ›์ง€ ๋ชปํ•œ ๊ฐ•์˜์ž…๋‹ˆ๋‹ค.
๋ชจ๋‘์—๊ฒŒ ๋„์›€์ด ๋˜๋Š” ์ˆ˜๊ฐ•ํ‰์˜ ์ฃผ์ธ๊ณต์ด ๋˜์–ด์ฃผ์„ธ์š”!