RIBs๋ ์ฐ๋ฒ์์ ๋ง๋ cross ์ํคํ ์ณ ํจํด์ด๋ผ๊ณ ํฉ๋๋ค
rib ์ด๋ฆ์์ ์ ์ ์๋ฏ์ด
router, interactor, builder ์ด ์ธ๊ฐ์ง๊ฐ ํต์ฌ์ด๊ตฌ ์ด๋ค์ ์ฐจ์ฐจ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค !
๊ทธ์ค ์ค๋์ tutorial1์ ์ฐ๋ฒ์์ ์ ๊ณตํ wiki์ ํจ๊ป ์์ธํ ๋ฐ๋ผ ํด๋ณผ๊ฑฐ์์
https://github.com/uber/RIBs/wiki/iOS-Tutorial-1
ํ์ผ์ ์ด๋ฉด LoggedOut, Root ํด๋๊ฐ ์์ต๋๋ค
์ฑ์ด ์์๋๋ฉด AppDelegate๊ฐ ๋ฃจํธ RIB๋ฅผ ๋น๋ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ ์ ์ด๋ฅผ ๋ฃจํธ RIB๋ก ์ ์กํฉ๋๋ค.
์ด๋ ๊ฒ ๋น์ทํ ํจ์ ์ฐพ์ ๋์ฒดํด ์ฃผ์์ด์ !
์๋๋ก ๋ด๋ ค RIBs ์ ํํ ๋ค
์ด๋ฆ์ LoggedOut์ด๋ผ ํ๊ณ Owns corresponding view ์ฒดํฌ ๋ฐ์ค ํด๋ฆญํด์ ํ์ผ์ ๋ง๋ค์ด์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด์ DELETE_Me ํ์ผ์ ์ญ์ ํด์ค๋๋ค.
ํํ ์ด์ ์์ฑ๋ ํ์ผ๋ค์ ์ดํดํด๋ด ์๋คใ
LoggedOutBuilder
์ฝ๋๋ฅผ ๋ณด๋ฉด LoggedOutBuildable protocol์ ์ค์ํ๊ณ ์๋๋ฐ ์ฌ๊ธฐ์ build๋ผ๋ ํจ์๊ฐ ์ ์๋์ด ์์ต๋๋ค.
build ํจ์ ๋ด์์๋ ~Component, ViewController, Interactor ๋ฑ๋ฑ ์์ง์ ์ ์ ์๋ ์์๋ค์ ์์ฑํ๊ณ ์๋ค์ ํ .. ์ผ๋จ ์ฌ๊ธฐ์ ๋์ด๊ฐ๊ณ ๋ค์ !!
LoggedOutInteractor
'Brain of the app' ์ด๋ผ๊ณ ์๊ฐํ๊ณ ์๋ค์ ์ฑ์ ํต์ฌ์ธ๊ฐ๋ด ๋๋ค.
๋ค๋ฅธ RIBs๋ก ์ ํํ๊ธฐ๋ ํ๊ณ , view controller์ model์ ๋ณด์ฌ์ฃผ๊ธฐ๋ ํ๋ค๊ณ ํ๋ค์ ์ผ๋จ ๋ ๋์ด๊ฐ ๋ด ์๋ค ..
LoggedOutRouter
Interactor์ ํต์ ํ๊ธฐ ์ํด LoggedOutInteractable์์ ํ์ํ ๊ฒ์ ์ ์ธํ๊ณ , LoggedOutViewControllable์ ์ฌ์ฉํ์ฌ ๋ทฐ ์ปจํธ๋กค๋ฌ์ ํต์ ํฉ๋๋ค
LoggedOutViewController
LoggedOutPresentableListener๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ณณ์ ๋๋ค
์ด์ loggedOut UI๋ฅผ ๋ง๋ค๋ฌ ๋์ด๊ฐ๋ด ์๋ค !!
์น์ ํ๊ฒ๋ loggedoutViewController์ ๋ฃ์ ์ฝ๋๋ฅผ ์ ๊ณตํด์คฌ์ด์ ์๋ ์ฝ๋๋ฅผ
listener ๋ฐ์ ๋ฃ์ด์ค๋๋ค
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
let playerFields = buildPlayerFields()
buildLoginButton(withPlayer1Field: playerFields.player1Field, player2Field: playerFields.player2Field)
}
// MARK: - Private
private var player1Field: UITextField?
private var player2Field: UITextField?
private func buildPlayerFields() -> (player1Field: UITextField, player2Field: UITextField) {
let player1Field = UITextField()
self.player1Field = player1Field
player1Field.borderStyle = UITextBorderStyle.line
view.addSubview(player1Field)
player1Field.placeholder = "Player 1 name"
player1Field.snp.makeConstraints { (maker: ConstraintMaker) in
maker.top.equalTo(self.view).offset(100)
maker.leading.trailing.equalTo(self.view).inset(40)
maker.height.equalTo(40)
}
let player2Field = UITextField()
self.player2Field = player2Field
player2Field.borderStyle = UITextBorderStyle.line
view.addSubview(player2Field)
player2Field.placeholder = "Player 2 name"
player2Field.snp.makeConstraints { (maker: ConstraintMaker) in
maker.top.equalTo(player1Field.snp.bottom).offset(20)
maker.left.right.height.equalTo(player1Field)
}
return (player1Field, player2Field)
}
private func buildLoginButton(withPlayer1Field player1Field: UITextField, player2Field: UITextField) {
let loginButton = UIButton()
view.addSubview(loginButton)
loginButton.snp.makeConstraints { (maker: ConstraintMaker) in
maker.top.equalTo(player2Field.snp.bottom).offset(20)
maker.left.right.height.equalTo(player1Field)
}
loginButton.setTitle("Login", for: .normal)
loginButton.setTitleColor(UIColor.white, for: .normal)
loginButton.backgroundColor = UIColor.black
loginButton.addTarget(self, action: #selector(didTapLoginButton), for: .touchUpInside)
}
@objc private func didTapLoginButton() {
}
๊ทธ๋ฆฌ๊ณ build ํด๋ณด๋ฉด ?
์์ ํ๋ฉด๊ณผ ๊ฐ์ด ์ ๋์ค๋ค์ !
์ด์ ๋ ๋ก๊ทธ์ธ ๋ฒํผ์ ํด๋ฆญํ์๋์ ๋ก์ง์ ๋ํด ์๊ฐํด๋ด ์๋ค.
login button์ ํด๋ฆญํ๋ฉด
LoggedOutViewController๋ ๋ฆฌ์ค๋(LoggedOutPresentableListener)๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ? ๋ก๊ทธ์ธ ์์ฒญ์ ์งํํ๊ธฐ ์ํด ๊ฒ์์ ์ฐธ์ฌํ๋ ํ๋ ์ด์ด์ ์ด๋ฆ์ด ํ์ํฉ๋๋ค. ๊ทธ๋ฌ๊ธฐ ์ํด์ ๋ทฐ ์ปจํธ๋กค๋ฌ์์ ๋ก๊ทธ์ธ ์์ฒญ์ ์์ ํ ์ ์๋๋ก ๋ฆฌ์ค๋๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํฉ๋๋ค.
LoggedOutPresentableListener ํ๋กํ ์ฝ์ ์๋ ํจ์๋ฅผ ์์ฑํด ์ค๋๋ค.
protocol LoggedOutPresentableListener: AnyObject {
// TODO: Declare properties and methods that the view controller can invoke to perform
// business logic, such as signIn(). This protocol is implemented by the corresponding
// interactor class.
func login(withPlayer1Name player1Name: String?, player2Name: String?)
}
login player์ name์ด ์ต์ ๋๋ก ๋์ด ์์ต๋๋ค. ์ด๋ ํ๋ ์ด์ด๊ฐ ์ด๋ฆ์ ์ ๋ ฅํ์ง ์์์๋ ์๊ธฐ ๋๋ฌธ์ด์ฃ !
๋ฐ๋ผ์ LoggedOutPresentableListener์ ์ค์ํ๋ ํ์ผ์ ์ฐพ์๊ฐ๋ณด๋ฉด ?
LoggedOutInteractor๊ฐ ์๋ค์ !! login ํจ์๋ฅผ ์์ฑํด์ค๋๋ค.
func login(withPlayer1Name player1Name: String?, player2Name: String?) {
let player1NameWithDefault = playerName(player1Name, withDefaultName: "Player 1")
let player2NameWithDefault = playerName(player2Name, withDefaultName: "Player 2")
print("\(player1NameWithDefault) vs \(player2NameWithDefault)")
}
private func playerName(_ name: String?, withDefaultName defaultName: String) -> String {
if let name = name {
return name.isEmpty ? defaultName : name
} else {
return defaultName
}
}
๊ทธ๋ฆฌ๊ณ ๋ค์ login ํด๋ฆญํ๋ ํจ์๋ก ๋์๊ฐ
@objc private func didTapLoginButton() {
listener?.login(withPlayer1Name: player1Field?.text, player2Name: player2Field?.text)
}
listener๋ฅผ ์ฐ๊ฒฐํด์ค๋๋ค.
๋ค์ ๋น๋ํด๋ณผ๊น์ ?
์ด๋ ๊ฒ ํํ ๋ฆฌ์ผ 1์ด ๋๋ฌ์ต๋๋ค ใ ใ
๋ญ๊ฐ RIBs๋ฅผ ์ด๋ฃจ๊ณ ์๋ ๋ผ๋์ ์ด๋ฆ์ ๋ฐ๋ฅธ ์ฐ์์๋ฅผ ์๊ฒ ๊ฐ๊ธฐ๋ ํ๊ณ ์์ง์ ๊ตฌ์กฐ๊ฐ ์ฝํ ์๋ ๋๋์ด ๋๋ค์ ..
๋ค์ ํํ ๋ฆฌ์ผ์ ๋ณด๋ฉด์ ๋ ์ดํดํด๋ณด๋๋ก ํด์ผ๊ฒ ์ด์
๊ธ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค ~~
'IOS๐ > ์ํคํ ์ณ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ํคํ ์ณ] RIBs๋ (0) | 2022.05.06 |
---|---|
[์ํคํ ์ณ] ReactorKit์ด๋ (0) | 2022.04.24 |
[์ํคํ ์ณ] MVP ๋ (0) | 2022.01.06 |
[์ํคํ ์ณ] MVVM (clean-architecture) ์ด๋ (0) | 2021.12.22 |
[์ํคํ ์ณ] Viper ๋ (0) | 2021.11.29 |
๋๊ธ