Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
285 changes: 279 additions & 6 deletions 34th-SOPT-iOS-DanggeunCloneCoding.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,174 @@
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>SnapKitPlayground (Playground) 1.xcscheme</key>
<key>ReactiveSwift (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>5</integer>
</dict>
<key>ReactiveSwift (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>6</integer>
</dict>
<key>ReactiveSwift (Playground) 3.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>22</integer>
</dict>
<key>ReactiveSwift (Playground) 4.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>23</integer>
</dict>
<key>ReactiveSwift (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>24</integer>
</dict>
<key>ReactiveSwift (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>4</integer>
</dict>
<key>ReactiveSwift-UIExamples (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>SnapKitPlayground (Playground) 2.xcscheme</key>
<key>ReactiveSwift-UIExamples (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
</dict>
<key>SnapKitPlayground (Playground).xcscheme</key>
<key>ReactiveSwift-UIExamples (Playground) 3.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>19</integer>
</dict>
<key>ReactiveSwift-UIExamples (Playground) 4.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>20</integer>
</dict>
<key>ReactiveSwift-UIExamples (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>21</integer>
</dict>
<key>ReactiveSwift-UIExamples (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>Rx (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>12</integer>
</dict>
<key>Rx (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>13</integer>
</dict>
<key>Rx (Playground) 3.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>10</integer>
</dict>
<key>Rx (Playground) 4.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>14</integer>
</dict>
<key>Rx (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>15</integer>
</dict>
<key>Rx (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>11</integer>
</dict>
<key>SnapKitPlayground (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>8</integer>
</dict>
<key>SnapKitPlayground (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>9</integer>
</dict>
<key>SnapKitPlayground (Playground) 3.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>16</integer>
</dict>
<key>SnapKitPlayground (Playground) 4.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>17</integer>
</dict>
<key>SnapKitPlayground (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>18</integer>
</dict>
<key>SnapKitPlayground (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>7</integer>
</dict>
</dict>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// LoginViewController_MVVMObservable.swift
// 34th-SOPT-iOS-DanggeunCloneCoding
//
// Created by 김민성 on 2024/05/31.
//

import UIKit
import SnapKit

final class LoginViewController_MVVMObservable: UIViewController {

private let rootView = LoginView()
private let viewModel = LoginViewModel_Observable()

override func loadView() {
self.view = rootView
}

override func viewDidLoad() {
super.viewDidLoad()

self.view.backgroundColor = .white

setTarget()
bindViewModel()
}

private func setTarget() {
rootView.loginButton.addTarget(self, action: #selector(loginButtonDidTap), for: .touchUpInside)
}

private func bindViewModel() {
viewModel.isValid.bind { [weak self] isValid in
guard let isValid else { return }
if isValid { self?.pushToWelcomeVC() }
}

viewModel.errMessage.bind { [weak self] err in
guard let err else { return }
self?.showToast(err)
}
}


@objc private func loginButtonDidTap() {
viewModel.checkValid(
id: rootView.idTextField.text,
password: rootView.passwordTextField.text
)
}

private func pushToWelcomeVC() {
let welcomeViewController = WelcomeViewController()
self.navigationController?.pushViewController(welcomeViewController, animated: true)
}

func showToast(_ message: String,
bottomInset: CGFloat = 86
) {
guard let view else { return }
Toast().show(message: message,
view: view,
bottomInset: bottomInset
)
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// LoginViewModel_Observable.swift
// 34th-SOPT-iOS-DanggeunCloneCoding
//
// Created by 김민성 on 2024/05/31.
//

import UIKit

final class LoginViewModel_Observable {
var isValid: ObservablePattern<Bool> = ObservablePattern<Bool>.init(false)
var errMessage: ObservablePattern<String> = ObservablePattern<String>.init(nil)

func checkValid(id: String?, password: String?) {
guard let id else {
errMessage.value = "아이디가 비어있습니다."
return
}
guard let password else {
errMessage.value = "비밀번호가 비어있습니다."
return
}

let idRegEx = "[A-Za-z0-9]{5,13}"
let pwRegEx = "[A-Za-z0-9!_@$%^&+=]{8,20}"

guard let _ = id.range(of: idRegEx, options: .regularExpression) else {
errMessage.value = "아이디가 유효하지 않습니다."
return
}

guard let _ = password.range(of: pwRegEx, options: .regularExpression) else {
errMessage.value = "비밀번호가 유효하지 않습니다."
return
}
isValid.value = true

}
}
Loading