Skip to content

Commit

Permalink
[Feat] 닉네임 생성 MVVM 적용 (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
seuriseuljjeok committed May 30, 2024
1 parent da84091 commit ae81c15
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
CA3953252BC6FB1100B15E91 /* ScreenUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA3953242BC6FB1100B15E91 /* ScreenUtils.swift */; };
CA3BA70F2BFE7E9800F77616 /* MainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA3BA70E2BFE7E9800F77616 /* MainViewModel.swift */; };
CA803D982C05B977006B8C35 /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA803D972C05B977006B8C35 /* LoginViewModel.swift */; };
CA803D9A2C0866BA006B8C35 /* ObservablePattern.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA803D992C0866BA006B8C35 /* ObservablePattern.swift */; };
CA8496E22BE7E36D0064E0CC /* Moya in Frameworks */ = {isa = PBXBuildFile; productRef = CA8496E12BE7E36D0064E0CC /* Moya */; };
CA8496E52BE7E54D0064E0CC /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA8496E42BE7E54D0064E0CC /* Config.swift */; };
CA8496E72BE7E8E60064E0CC /* GetMovieResponseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA8496E62BE7E8E60064E0CC /* GetMovieResponseModel.swift */; };
Expand Down Expand Up @@ -92,6 +93,7 @@
CA3953242BC6FB1100B15E91 /* ScreenUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenUtils.swift; sourceTree = "<group>"; };
CA3BA70E2BFE7E9800F77616 /* MainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewModel.swift; sourceTree = "<group>"; };
CA803D972C05B977006B8C35 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = "<group>"; };
CA803D992C0866BA006B8C35 /* ObservablePattern.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservablePattern.swift; sourceTree = "<group>"; };
CA8496E42BE7E54D0064E0CC /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
CA8496E62BE7E8E60064E0CC /* GetMovieResponseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetMovieResponseModel.swift; sourceTree = "<group>"; };
CA8496E92BE89A840064E0CC /* BaseTargetType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTargetType.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -300,6 +302,7 @@
isa = PBXGroup;
children = (
CA3953242BC6FB1100B15E91 /* ScreenUtils.swift */,
CA803D992C0866BA006B8C35 /* ObservablePattern.swift */,
);
path = Utils;
sourceTree = "<group>";
Expand Down Expand Up @@ -542,6 +545,7 @@
files = (
CA8496FC2BE948590064E0CC /* ParamountView.swift in Sources */,
CA902EF92BDE9E6700560D26 /* HistoryViewController.swift in Sources */,
CA803D9A2C0866BA006B8C35 /* ObservablePattern.swift in Sources */,
CA3953002BC44B9900B15E91 /* UIView+.swift in Sources */,
CA1F68F02BD5691D00439E33 /* MainViewController.swift in Sources */,
CA8496F22BE8A6700064E0CC /* NetworkResult.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// ObservablePattern.swift
// Tving_CloneProject
//
// Created by 윤희슬 on 5/30/24.
//

import Foundation

class ObservablePattern<T> { // --- a

var value: T? { // --- b
didSet {
self.listener?(value)
}
}

init(_ value: T?) {
self.value = value
}

private var listener: ((T?) -> Void)? // --- c

func bind(_ listener: @escaping (T?) -> Void) {
listener(value) // 생략 가능, 여기선 시작되는 순간부터 초기값을 갖고 동작하기 위해 사용
self.listener = listener
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,6 @@ private extension LoginView {
let id = self.idTextField.text
let pw = self.pwTextField.text

if loginViewModel.checkId(id: id) {
idClearButton.isHidden = false
} else {
pwClearButton.isHidden = false
maskButton.isHidden = false
}

setLoginButton(isEnabled: loginViewModel.checkValid(id: id, pw: pw))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class CreateNicknameViewController: UIViewController {

weak var delegate: CreateNicknameVCDelegate?

private let loginViewModel: LoginViewModel = LoginViewModel()


// MARK: - Life Cycles

Expand Down Expand Up @@ -131,7 +133,6 @@ private extension CreateNicknameViewController {
}

warningLabel.do {
$0.text = "닉네임은 \"한글\"만 사용 가능해요!"
$0.font = UIFont.pretendard(.subhead5)
$0.textColor = UIColor(resource: .red)
$0.isHidden = true
Expand Down Expand Up @@ -167,8 +168,7 @@ private extension CreateNicknameViewController {

@objc
func textFieldChange() {
let nickname = self.nicknameTextField.text ?? ""
setSaveButton(isEnabled: !nickname.isEmpty)
setSaveButton(isEnabled: loginViewModel.checkValidNickname(nickname: self.nicknameTextField.text))
}

@objc
Expand All @@ -192,15 +192,14 @@ private extension CreateNicknameViewController {
extension CreateNicknameViewController: UITextFieldDelegate {

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// 정규식 패턴
let pattern = "^[ㄱ-ㅎㅏ-ㅣ가-힣]*$"

// 입력된 문자열이 패턴과 일치하는지 확인
if let _ = string.range(of: pattern, options: .regularExpression) {
if loginViewModel.checkValidNickname(nickname: textField.text) {
self.warningLabel.isHidden = true
return true
} else {
self.warningLabel.isHidden = false
self.warningLabel.text = loginViewModel.fetchErrMessage()
setSaveButton(isEnabled: false)
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class LoginViewController: UIViewController {

var nickname: String = ""

private let loginViewModel: LoginViewModel = LoginViewModel()


// MARK: - Life Cycles

Expand Down Expand Up @@ -180,7 +182,7 @@ extension LoginViewController: LoginViewDelegate {

func pushToWelcomeVC(id: String) {
let welcomeVC = WelcomeViewController()
welcomeVC.userInfo = nickname.isEmpty ? id : nickname
welcomeVC.userInfo = loginViewModel.checkValidNickname(nickname: self.nickname) ? nickname : id
self.navigationController?.pushViewController(welcomeVC, animated: true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,66 @@ final class LoginViewModel {

// MARK: - Properties

var errMessage: String = ""
var id: ObservablePattern<String> = ObservablePattern<String>.init(nil)

var pw: ObservablePattern<String> = ObservablePattern<String>.init(nil)

var nickname: ObservablePattern<String> = ObservablePattern<String>.init(nil)

var errMessage: ObservablePattern<String> = ObservablePattern<String>.init(nil)

}

extension LoginViewModel {

func checkValid(id: String?, pw: String?) -> Bool {
guard let id else {
errMessage = "아이디를 입력해주세요"
func checkEmptyNickname(nickname: String?) -> Bool {
guard let nickname else {
errMessage.value = "닉네임을 입력해주세요"
return false
}

guard let pw else {
errMessage = "비밀번호를 입력해주세요"
self.nickname.value = nickname
return true
}

func checkValidNickname(nickname: String?) -> Bool {
guard let nickname else {
errMessage.value = "닉네임을 입력해주세요"
return false
}

// 정규식 패턴
let pattern = "^[ㄱ-ㅎㅏ-ㅣ가-힣]*$"
guard let _ = nickname.range(of: pattern, options: .regularExpression) else {
errMessage.value = "닉네임은 \"한글\"만 사용 가능해요!"
return false
}

self.nickname.value = nickname
return true
}

func checkId(id: String?) -> Bool {
func checkValid(id: String?, pw: String?) -> Bool {
guard let id else {
errMessage.value = "아이디를 입력해주세요"
return false
}
self.id.value = id

guard let pw else {
errMessage.value = "비밀번호를 입력해주세요"
return false
}
self.pw.value = pw

return true
}

func clearText(textfield: UITextField) {
textfield.text = ""
}

func fetchErrMessage() -> String? {
return self.errMessage.value
}
}

0 comments on commit ae81c15

Please sign in to comment.