
์์ ์ฌ์ง๊ณผ ๊ฐ์ด 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..
์ต๊ทผ, ์ํคํ ์ฒ ๊ด๋ จ ๊ณต๋ถ๋ฅผ ์งํํ๋ฉด์ 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..
FCM์ ์ค์ ํ๋ ๋์ค, Build๋จ๊ณ์์ Default app has already been configured. ๋ผ๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค... ๊ทธ๋์, ์คํ์ ๋ฐ๋ผ ์ฌ๋ผ๊ฐ๋ณด๋ ์๋์ ๊ฐ์ ์ฝ๋์ ๋์ฐฉํ๊ฒ ๋์์ต๋๋ค. ํด๊ฒฐ์ ์ํด ์์ ์ฝ๋๋ฅผ ์ฝ์ด๋ณด๋, // Only extensions should potentially be able to call 'configure' more than onse ๋ผ๊ณ ์์ฑ๋์ด ์๋ ์ฃผ์ ๋ณด์ด์๋์?? ํด์ ํด๋ณด๋ฉด, '์ด ์์ธ๋, ์ ์ฌ์ ์ผ๋ก 'configure'๊ฐ 1๋ฒ ์ด์ ๋ฐ์ํ ์ ์์ ๋ ๋ถ๋ ค์ง๋๋ค.' ๋ผ๋ ์๋ฏธ์ ๋๋ค. ๊ทธ๋ฌ๋๊น, ์ฐ๋ฆฌ๊ฐ ์ฒ์ Firebase๋ฅผ ์ค์ ํ ๋ Firebase.configure() ์๋์ด 2๋ฒ ์ด์ ํธ์ถ๋์๋ค๋ ์๋ฏธ๊ฒ ์ฃ ? ๊ทธ๋์ ์ค์ ๋ก ..

RxSwift๋ฅผ ์ฌ์ฉํ์ง ์์ KeyboardNotification ๋ค๋ฃจ๊ธฐ ๊ฐ๋ฐ์ ํ๋ค๋ณด๋ฉด, TextField๋ฅผ ์ ํํ์์ ๋ ํด๋น TextField์์ญ์ KeyBoard๊ฐ ์นจ๋ฒํ์ฌ [1] ์์ฑํ๋ ๋ด์ฉ [2] ์๋ฃ ๋ฒํผ ๋ฑ์ ๊ฐ๋ฆฌ๋ ์ด์๊ฐ ๋ฐ์ํ๊ณค ํฉ๋๋ค. ํด๋น ์ด์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ Notification์ด๋ผ๋ Class๋ฅผ ์ฌ์ฉํด์ผํฉ๋๋ค. UIScrollView ๋ด๋ถ์ ์ ์๋์ด ์๋ TextField์ ๊ฒฝ์ฐ์๋ ์๋์ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด TextField๋ฅผ ์ ํ ํ์์ ๋, KeyBoard์ ๋์ด๋งํผ ScrollView๊ฐ ์ฌ๋ผ๊ฐ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. class SignUpViewController: BaseViewController{ var keyBoardUpDown = false override fu..