ํ๋ก์ ํธ์ ํด๋ ๊ตฌ์กฐ๋ฅผ ํ์ ํด์ฃผ๋ ๋๊ตฌ์ธ Codeface๋ฅผ ์๊ฐํด ๋ณด๊ณ ์ ํฉ๋๋ค. ์ด์ ๊ฐ์ ํด์ด, ๊ธฐ์กด์๋ ์์๋์ง๋ ๋ชจ๋ฅด์ง๋ง, ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ ๊ฒ ๊ฐ์ ์๊ฐํ๋๋ก ํ๊ฒ ์ต๋๋ค. Codeface ์ค์น ์ฐ์ ๊ณต์ ์ฌ์ดํธ์ ๋ค์ด๊ฐ๋๋ค. https://codeface.io/ Codeface See the Architecture of any Codebase codeface.io ํด๋น ์ฌ์ดํธ์ ๋ค์ด๊ฐ๋ฉด ํ๋จ์, ์ฑ์คํ ์ด ๋งํฌ๊ฐ ์์ผ๋ ์ค์น ํด์ค๋๋ค. ์ด ๋๊ตฌ๋, LSPService๋ผ๋ ์คํ์์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ๊ณต๋๋ ์๋น์ค ์ ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์, ๋จผ์ LSPService๋ฅผ ์ค์น ํด์ค๋๋ค. ๊ณต์์ฌ์ดํธ ์ตํ๋จ์ ์๋ LSPService ๋งํฌ๋ฅผ ๋๋ฅด๋ฉด, ์ค์น ๋ฐฉ๋ฒ์ ๋ํด ๋์ต๋๋ค. ์ด๋ํ ๋งํฌ์์, ๊ฐ์ ํ๋ก์ธ..
์์ ์ฌ์ง๊ณผ ๊ฐ์ด UIComponent๋ฅผ ์ถ๊ฐํ๊ณ , Auto Layout์ ์ค์ ํ๋ ค๊ณ ํ๋๋ฐ ํ๋จ์ 'Add New Constraints'๊ฐ ํ์ฑํ ๋์ง ์๋ ํ์์ ๋ณด์ด๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ๊ทธ๋ด ๋, ์ฐ์ธก ์ฌ์ด๋๋ฐ์ 'Show The Size Inspector'๋ฅผ ๋ค์ด๊ฐ์ 'Layout'ํญ๋ชฉ์ ๊ฐ์ด 'Autoresizing Mask'๋ก ๋์ด์๋์ง ํ์ธ ํด์ค๋ค. ๋ง์ฝ ๊ทธ๋ ๊ฒ ๋์ด์๋ค๋ฉด, 'Inferred'๊ฐ์ผ๋ก ๋ณ๊ฒฝ ํด์ค๋ค.
Clean Architecture๋ฅผ ๊ณต๋ถํ๋ฉด์ ํท๊ฐ๋ฆฌ๋ ๊ฐ๋ ์ด์๋ '์์กด์ฑ ์ฃผ์ (Dependency Injection)'์ ๋ํ ์ ๋ฆฌ๋ฅผ ํ๋ ค๊ณ ํฉ๋๋ค. ๋ค๋ง, Clean Architecture์ ๋ํ ์ ๊ณผ์ ์ ๋ค๋ฃจ๋ ๊ธ์ด ์๋๋ ์ด ์ ์ฐธ๊ณ ๋ถํ๋๋ฆฝ๋๋ค. ๋ํ ์๋ฒฝํ ๊ธ์ด ์๋๋ค๋ณด๋, ์๋ชป๋ ๋ด์ฉ์ด ์์ ์ ์์ผ๋ ๋ง์ ์ง์ ๋ถํ๋๋ฆฌ๊ฒ ์ต๋๋ค! :) ์์กด์ฑ(Dependency)์ด๋? ํํ, Clean Architecture์ ๊ฐ์ฅ ์ค์ํ ์์น์ ์ค๋ช ํ ๋ "๊ฐ ๊ณ์ธต(Layer)์ ์๋ก ๋ ๋ฆฝ์ ์ด์ด์ผ ํ๋ฉฐ, ํ ๊ณ์ธต์ ๋ณํ๊ฐ ๋ค๋ฅธ ๊ณ์ธต์ ์ํฅ์ ์ฃผ์ด์๋ ์๋๋ค!" ๋ผ๊ณ ์ค๋ช ํฉ๋๋ค. ์ฌ๊ธฐ์ ๋งํ๋ '๊ณ์ธต์ด ์๋ก ๋ ๋ฆฝ์ ' ์ด๋ผ๋ ๋ง์, ๊ฐ ๊ณ์ธต์ ๊ฒฐํฉ๋๋ฅผ ์ต์ํ ํ๋๊ฒ์ ์งํฅํด์ผํ๋ค๋ ๋ง ์ ๋๋ค. ํ์ง๋ง, iO..
์ด์ ์ action์ด ์๋, outlet๊ด๋ จํด์ ๋์ผํ Error๊ฐ ๋ฐ์ํ ์ ์ด ์์ด์ ์ด๋ฒ์ ๊ธ๋ก ๋จ๊น๋๋ค. ์ ์๋ฌ๋, Xibํ์ผ์์ ViewController๋ก ์ง์ Outlet์ด๋ Action์ ์ฐ๊ฒฐ ํ ๋ ์๊ธฐ๋ ์๋ฌ์ ๋๋ค. ๋ฐ์ ์์ธ์ ์ ํํ๊ฒ๋ ๋ชจ๋ฅด๊ฒ ์ผ๋, ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ ๋ค ๋์ผํฉ๋๋ค. ์ฐ์ VC๋ด๋ถ์ ์ง์ Outlet๋ณ์ ํน์ Actionํจ์๋ฅผ ์ ์ ํด์ค๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ธฐ์กด๊ณผ๋ ์ญ์์ผ๋ก, ์ฌ์ง์ ์ข์ธก Action ์ฐ๊ฒฐ๋ถ์์ Xibํ์ผ์ Component๋ก ์ฐ๊ฒฐ ํด์ฃผ๋ฉด ์ ์์ ์ผ๋ก ์ฐ๊ฒฐ์ด ๋ฉ๋๋ค.
์ธํด์ฝ์ ์งํํ๋ฉฐ, iOS์์์ ๋น๋์ค ์ฒ๋ฆฌ๊ธฐ์ ์ ๋ํ ๊ณต๋ถ๋ฅผ ์งํํ๊ณ ์์ต๋๋ค. ๊ทธ ์ค ๊ฐ์ฅ ๋จผ์ ์์๋ด์ผ ํ , ์ฝ๋ฑ์ ๋ํด ๊ฐ์ธ์ ์ผ๋ก ๊ณต๋ถํ๊ณ ์ ๋ฆฌํ ๊ธ์ ๋๋ค. ์ฝ๋ฑ์ด๋? ์ฝ๋ฑ์ coder-decoder์ ์ฝ์์ด๋ค. ์ค๋์ค & ๋น๋์ค ์ ํธ์ ๊ฐ์ ๋์งํธ ๋ฐ์ดํฐ๋ฅผ ํน์ ํ์์ผ๋ก ์ธ์ฝ๋ฉ ๋ฐ ๋์ฝ๋ฉ ํ๋ SW & HW ์ฅ์น ์ธ์ฝ๋ฉ. ๋์ฝ๋ฉ ๊ฐ๋ [ ์ธ์ฝ๋ฉ ] ์ธ์ฝ๋ฉ์ด๋ ์ ์ก or ์ ์ฅ์ ์ฉ์ดํ๊ฒ ํ๊ธฐ ์ํด ์ ๋ณด๋ฅผ ํ ํ์์์ ๋ค๋ฅธ ํ์์ผ๋ก ๋ณํํ๋ process ์ด๋ค. ๋ณํ ํ๊ณ ์ํ๋ data์ ์ข ๋ฅ์, ์ธ์ฝ๋ฉ์ ๋ชฉ์ ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ํ ๊ฐ๋ฅํ๋ค. ex1) ๋ผ๋์ค ์ ํธ์ ๊ฐ์ ๋ ธ์ด์ฆ๊ฐ ๊ฐ๋ํ ์ํต ์ฑ๋์ ํตํด text๋ฅผ ์ ์กํ๋ ๊ณผ์ . ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๊ณผ์ ์์ ๋ ธ์ด์ฆ๋ก ์ธํ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ..
์ต๊ทผ, ์ํคํ ์ฒ ๊ด๋ จ ๊ณต๋ถ๋ฅผ ์งํํ๋ฉด์ Input/Outputํจํด์ ๊ณต๋ถํด ๋ณธ ๊ฒฝํ์ด ์์ต๋๋ค..! ์ด๋ฌํ Input/Output ํจํด์ ์ฌ์ฉํ ๋, ์ ํํ ๋๊ณ ๋ฐ๋ณต๋ ์ฝ๋๋ฅผ ์ค์ด๊ธฐ ์ํด ViewModelProtocol๋ฅผ ์ ์ธํ์ฌ ํด๋น ํ๋กํ ์ฝ์ ์ด์ฉํ๋ ๋ฐฉ์์ ๋ง์ด ์ฌ์ฉํฉ๋๋ค. ๋ณดํธ์ ์ผ๋ก, ์๋์ ๊ฐ์ด ๋ง์ด ์ ์ธํ์ฌ ์ฌ์ฉํฉ๋๋ค protocol ViewModelType { associatedtype Input associatedtype Output func transform(input: Input) -> Output } (๋ฌผ๋ก , MVVMํจํด๊ณผ RxSwift๋ฅผ ํผ์ฉํ์ฌ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ํด๋น ํ๋กํ ์ฝ์ disposeBag์ ์ ์ธํ๊ธฐ๋ ํฉ๋๋ค) ์ด๋, Input๊ณผ Output ์์ ๋ถ์ด์๋ associ..
@discardableResult ์ด๋? discardable์ ๊ทธ๋๋ก ํด์ํ๋ฉด, ๋ฒ๋ฆด ์ ์๋(ํ๊ธฐํ ์ ์๋) ์ด๋ผ๋ ๋ป ์ ๋๋ค. ์ฆ, discardableResult๋ฅผ ํด์ํ๋ฉด '๊ฒฐ๊ณผ๊ฐ์ ๋ฒ๋ฆด ์ ์๋' ์ด๋ผ๋ ์๋ฏธ๊ฐ ๋ฉ๋๋ค. ๋ฐ๋ผ์ @discadableResult๋ ํจ์์ return๊ฐ์ ๋ฒ๋ ค์ค ๋ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค. ๐๐ป Return๊ฐ์ด ์กด์ฌํ๋ ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ์ง ์์ ์ ๋ํ๋๋ warning์ ์ง์์ฃผ๋ ์ญํ ์ ํฉ๋๋ค. @discardableResult ์์ @discardableResult๋ฅผ ์ฌ์ฉํ๋ฉด, ์์๊ฐ์ด ๋ ธ๋์ warning ๋ฉ์ธ์ง๊ฐ ์ฌ๋ผ์ง๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์น๋ทฐ๋ฅผ ๋จ์ํ ๋ถ๋ฌ์ค๊ธฐ๋ง ํ๋ฉด, iOS์์ ๋ง์ด ์ฌ์ฉํ๋ ์ค์์ดํ ์ ์ค์ณ๋ฅผ ํตํด ๋ค๋ก๊ฐ๊ธฐ & ์์ผ๋ก ๊ฐ๊ธฐ ๋์์ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅ ํฉ๋๋ค. ์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ , ์๋์ ์ฝ๋์ ๊ฐ์ด ์์ฑํด์ฃผ๋ฉด ๋ฉ๋๋ค. extension ViewController: WKNavigationDelegate { override func viewDidLoad(){ //MARK: ๋ธ๋ฆฌ๊ฒ์ดํธ ์ ์ธ webView.navigationDelegate = self view.addSubview(webView) if let url = URL(string:"๋ณธ์ธ์ด ํจํค์ง ํ ๋๋ฉ์ธ"){ let request = URLRequest(url:url) webView.load(request) } //MARK: ์ค์์ดํ ์ ์ค์ณ๋ก ๋ค๋ก๊ฐ๊ธฐ&์์ผ๋ก๊ฐ๊ธฐ webV..