
์๋ ํ์ธ์!์กฐ๊ธ ๋ฆ์ ๊ฐ์ด ์์ง๋ง, Swift 5.9์์๋ถํฐ ์ ๊ณตํ๊ธฐ ์์ํ macro์ ๋ํด ๊ณต๋ถํด ๋ณด๊ณ ์WWDC 23 - Write Swift macros ์ธ์ ์ ๋ฃ๊ณ ์ ๋ฆฌํด ๋ณด์์ต๋๋ค. Swift์ macro๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด์ ๋ฐ๋ณต๋๋ ์ฝ๋๋ฅผ ์ปดํ์ผํ์์ ์์ฑํ์ฌ, ๊ฐ๋ฐ ์์ฐ์ฑ์ ๋์ฌ์ค๋ค.Overviewlet calculations = [ ( 1 + 1, "1 + 1" ), ( 2 + 3, "2 + 3" ), ( 7 - 3, "7 - 3" ), ( 5 - 2, "5 - 2" ), ( 3 * 2, "3 * 2" ), ( 3 * 5, "3 * 5" )]์ด๋ ๊ฒ ํ์๋ค์ด ๊ณ์ฐ ๋ฅ๋ ฅ์ ์ฐ์ตํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๊ณ์ฐ ๋ชฉ๋ก์ด ์๋ค.tuple์ ์ผ์ชฝ์๋ ์ ์ํ ๊ฒฐ๊ณผ๊ฐ ํ์๋๊ณ ..

ํด๋น ๊ธ์, ํ๋ฉด๋ฐฉ์ก์ ๋ํ ๊ฐ์ธ ๊ณต๋ถ๋ฅผ ์งํํ๋ฉฐ ์์ฒญํ WWDC 2018 - Live Screen Broadcast with ReplayKit์ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.ํด์๊ณผ ์ ๋ฆฌ๋ ๋ด์ฉ์ด ์๋ฒฝํ์ง ์์ผ๋ฏ๋ก, ์๋ชป๋ ๋ถ๋ถ์ ๋ํด์ ์ง์ ๋ถํ๋๋ฆฝ๋๋ค. ๐ 1. WWDC 2016 - Go Live with ReplayKit2. WWDC 2018 - Live Screen Broadcast with ReplayKit - ReplayKit์ ์ฌ์ฉ์์ App์ ํ๋ฉด, ์ค๋์ค ๋ฐ ๋ง์ดํฌ ์ฌ์ด๋๋ฅผ ์ค์๊ฐ์ผ๋ก ๊ธฐ๋กํ๊ณ ์์ ํ๊ณ ๊ณต์ ํ ์ ์๊ฒ ํด์ฃผ๋ ํ๋ ์์ํฌ์ด๋ค.- ReplayKit์ Live Broadcast๋ฅผ ์ง์ํ๋ค. ReplayKit ReplayKit์ ํ๋ฉด๊ณผ ์ค๋์ค ๊ทธ๋ฆฌ๊ณ 3rd-party ๋ผ์ด๋ธ์คํธ๋ฆฌ๋ฐ ์..

ํด๋น ๊ธ์, ํ๋ฉด๋ฐฉ์ก์ ๋ํ ๊ฐ์ธ ๊ณต๋ถ๋ฅผ ์งํํ๋ฉฐ ์์ฒญํ WWDC 2016 - Go Live with ReplayKit์ ์ ๋ฆฌํ ๊ธ ์ ๋๋ค.ํด์๊ณผ ์ ๋ฆฌ๋ ๋ด์ฉ์ด ์๋ฒฝํ์ง ์์ผ๋ฏ๋ก, ์๋ชป๋ ๋ถ๋ถ์ ๋ํด์ ์ง์ ๋ถํ๋๋ฆฝ๋๋ค. ๐ ReplayKit์ ์ฌ์ฉ์์ ์ฑ ๋ด ํ๋ฉด๊ณผ, ์ฌ์ด๋ ๊ทธ๋ฆฌ๊ณ ๋ง์ดํฌ์ ์ค๋์ค๋ฅผ ๋ นํํ ์ ์๋ค.์ด๋ฅผ ํตํด, ๊ฒ์์ ํ๋ ๋์ ์์ฑ ๋ด๋ ์ด์ ์ด ๊ฐ๋ฅํ๊ณ , ์ด๋ฅผ ์์คํ ๊ณต์ ์ํธ๋ฅผ ์ฌ์ฉํด์ ๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋ค.ReplayKit1. Replaykit์ HD ํ์ง์ ๋น๋์ค๋ฅผ ์ ๊ณตํ๋ค.๊ฒ์ ์ฑ๋ฅ์ ๊ฑฐ์ ์ํฅ์ ์ฃผ์ง ์๊ณ , ๋ฐฐํฐ๋ฆฌ์ ์๋ชจ๋ฅผ ์ต์ํ์ผ๋ก ์ค์2. ๊ฐ์ธ์ ๋ณด๋ฅผ ๋ณดํธํ๋ค์ ์ ์ ๊ฐ์ธ์ ๋ณด๊ฐ ๋งค์ฐ ์ค์ํ๊ธฐ ๋๋ฌธ์, ๋ นํ ์์ ์ ์ ์ฌ์ฉ์ ํ๋กฌํํธ๋ฅผ ํ์ํด์ ์ ์ ๊ฐ ์ง์ ๊ถํ์ ์ ๊ณตํ ์ ์๋๋ก..

์์ ์ฌ์ง๊ณผ ๊ฐ์ด 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..