ํ๋ก์ ํธ์ ํด๋ ๊ตฌ์กฐ๋ฅผ ํ์ ํด์ฃผ๋ ๋๊ตฌ์ธ 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๋ก ์ฐ๊ฒฐ ํด์ฃผ๋ฉด ์ ์์ ์ผ๋ก ์ฐ๊ฒฐ์ด ๋ฉ๋๋ค.
์ต๊ทผ, ์ํคํ ์ฒ ๊ด๋ จ ๊ณต๋ถ๋ฅผ ์งํํ๋ฉด์ 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..
ํ์์ ์์ ์ค์ด๋ Git์ Cloneํ๊ณ Buildํ๋ ๊ณผ์ ์์ Missing package product ~ ์ ๊ฐ์ Error๊ฐ ๋ฐ์ํ์์ต๋๋ค... ํด๋น ์๋ฌ๋, ๋จ์ํ cocoapod์ ์ธ๋ถ์์ ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ์ package ์ ๋ฐ์ดํธ๋, cache์ญ์ ๋ฑ๊ณผ ๊ฐ์ ๋น๊ต์ ๊ฐ๋จํ ํด๊ฒฐ๋ฒ์ด ์กด์ฌํฉ๋๋ค. (ํด๋น ํด๊ฒฐ๋ฒ์ ๊ตฌ๊ธ์ ๋ง์ด ์กด์ฌํ๋, ์ฐพ์๋ณด์๊ธธ ๋ฐ๋๋๋ค!) ํ์ง๋ง, ์ ํ์์ ์์ ์ค์ธ ํ๋ก์ ํธ๋ ์ฌ์ฉ ํ cocoapod์ submodule๋ก ๋ฑ๋กํ์ฌ ๊ด๋ฆฌํ์์ต๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ, Git ์ ์ฅ์์ submodule์ด ๋ด์ฅ๋์ด ์๋๋ฐ ๋จ์ Clone์ ํ๋ฉด submodule์ ์์น๋ฅผ ์ ํํ๊ฒ ์ก์ง ๋ชปํด์ Missing package product ์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ ํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ฒ์ Clo..