Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Login view, viewmodel, usecase #55

Merged
merged 12 commits into from
Nov 29, 2022
Merged
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
28 changes: 28 additions & 0 deletions DailyQuest/DailyQuest.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@
34091552292DE9D1007873A8 /* QuestEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5AC96DB292237C3003B7637 /* QuestEntity.swift */; };
340A7246293455CE00B26AA6 /* AuthRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A7245293455CE00B26AA6 /* AuthRepository.swift */; };
340A72472934573F00B26AA6 /* AuthRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A7245293455CE00B26AA6 /* AuthRepository.swift */; };
340A724929348B1B00B26AA6 /* AuthUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A724829348B1B00B26AA6 /* AuthUseCase.swift */; };
340A724B29348C2200B26AA6 /* DefaultAuthUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A724A29348C2200B26AA6 /* DefaultAuthUseCase.swift */; };
340FDFD3292B5CE300C4E3DC /* QuestsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CAE317292B19A3007653AD /* QuestsRepository.swift */; };
340FDFD4292B5DA100C4E3DC /* QuestUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3416FC87292B54DB00B504C5 /* QuestUseCase.swift */; };
340FDFD5292B5DB700C4E3DC /* DefaultQuestUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3416FC89292B560800B504C5 /* DefaultQuestUseCase.swift */; };
340FDFDB292B7A1500C4E3DC /* QuestViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340FDFDA292B7A1500C4E3DC /* QuestViewModelTests.swift */; };
340FDFDE292B7A2C00C4E3DC /* QuestUseCaseMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340FDFDD292B7A2C00C4E3DC /* QuestUseCaseMock.swift */; };
34113BE82934917500AB4919 /* AuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34113BE72934917500AB4919 /* AuthViewModel.swift */; };
34113BEB2934A3B200AB4919 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34113BEA2934A3B200AB4919 /* LoginViewController.swift */; };
34113BED2934BD3D00AB4919 /* TextFieldForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34113BEC2934BD3D00AB4919 /* TextFieldForm.swift */; };
3413139C291E480500E607E1 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3413139B291E480500E607E1 /* SnapKit */; };
3416FC88292B54DB00B504C5 /* QuestUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3416FC87292B54DB00B504C5 /* QuestUseCase.swift */; };
3416FC8A292B560800B504C5 /* DefaultQuestUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3416FC89292B560800B504C5 /* DefaultQuestUseCase.swift */; };
Expand Down Expand Up @@ -143,8 +148,13 @@

/* Begin PBXFileReference section */
340A7245293455CE00B26AA6 /* AuthRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRepository.swift; sourceTree = "<group>"; };
340A724829348B1B00B26AA6 /* AuthUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthUseCase.swift; sourceTree = "<group>"; };
340A724A29348C2200B26AA6 /* DefaultAuthUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultAuthUseCase.swift; sourceTree = "<group>"; };
340FDFDA292B7A1500C4E3DC /* QuestViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestViewModelTests.swift; sourceTree = "<group>"; };
340FDFDD292B7A2C00C4E3DC /* QuestUseCaseMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestUseCaseMock.swift; sourceTree = "<group>"; };
34113BE72934917500AB4919 /* AuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthViewModel.swift; sourceTree = "<group>"; };
34113BEA2934A3B200AB4919 /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = "<group>"; };
34113BEC2934BD3D00AB4919 /* TextFieldForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldForm.swift; sourceTree = "<group>"; };
3416FC87292B54DB00B504C5 /* QuestUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestUseCase.swift; sourceTree = "<group>"; };
3416FC89292B560800B504C5 /* DefaultQuestUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultQuestUseCase.swift; sourceTree = "<group>"; };
3416FC8D292B593C00B504C5 /* Quest+Stub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Quest+Stub.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -292,11 +302,20 @@
path = Mocks;
sourceTree = "<group>";
};
34113BE62934916B00AB4919 /* ViewModel */ = {
isa = PBXGroup;
children = (
34113BE72934917500AB4919 /* AuthViewModel.swift */,
);
path = ViewModel;
sourceTree = "<group>";
};
3416FC85292B549900B504C5 /* Home */ = {
isa = PBXGroup;
children = (
3416FC86292B54BF00B504C5 /* Protocols */,
3416FC89292B560800B504C5 /* DefaultQuestUseCase.swift */,
340A724A29348C2200B26AA6 /* DefaultAuthUseCase.swift */,
);
path = Home;
sourceTree = "<group>";
Expand All @@ -305,6 +324,7 @@
isa = PBXGroup;
children = (
3416FC87292B54DB00B504C5 /* QuestUseCase.swift */,
340A724829348B1B00B26AA6 /* AuthUseCase.swift */,
);
path = Protocols;
sourceTree = "<group>";
Expand Down Expand Up @@ -346,6 +366,7 @@
isa = PBXGroup;
children = (
342830A9292E12C700AE811B /* SettingsViewController.swift */,
34113BEA2934A3B200AB4919 /* LoginViewController.swift */,
);
path = ViewController;
sourceTree = "<group>";
Expand Down Expand Up @@ -415,6 +436,7 @@
3499551C292332DE007AB99E /* Cells */,
B50078D529222F3F0070AFC4 /* CircleCheckView.swift */,
3499551F29234637007AB99E /* CustomProgressBar.swift */,
34113BEC2934BD3D00AB4919 /* TextFieldForm.swift */,
);
path = Common;
sourceTree = "<group>";
Expand Down Expand Up @@ -501,6 +523,7 @@
3499551B292332B8007AB99E /* Settings */ = {
isa = PBXGroup;
children = (
34113BE62934916B00AB4919 /* ViewModel */,
342830ED292E189A00AE811B /* View */,
342830A5292E0F8600AE811B /* ViewController */,
342830A6292E0F9100AE811B /* Flow */,
Expand Down Expand Up @@ -1005,6 +1028,8 @@
34091552292DE9D1007873A8 /* QuestEntity.swift in Sources */,
342830F6292E1ACA00AE811B /* PlainItemViewModel.swift in Sources */,
34A529D129247880001BAD34 /* Coordinator.swift in Sources */,
34113BEB2934A3B200AB4919 /* LoginViewController.swift in Sources */,
340A724929348B1B00B26AA6 /* AuthUseCase.swift in Sources */,
3499552029234637007AB99E /* CustomProgressBar.swift in Sources */,
34A529E22924816A001BAD34 /* BrowseSceneDIContainer.swift in Sources */,
34A529E929248B58001BAD34 /* AppAppearance.swift in Sources */,
Expand Down Expand Up @@ -1044,11 +1069,13 @@
34874AA629252088000570DF /* AddQuestsViewController.swift in Sources */,
34642AB62925D9E40052FA0E /* UserInfoView.swift in Sources */,
349955292923600A007AB99E /* BrowseViewController.swift in Sources */,
34113BE82934917500AB4919 /* AuthViewModel.swift in Sources */,
34EE6EB72924C674005AF583 /* QuestView.swift in Sources */,
B58DFC0A29227DA800C68A4B /* CalendarCell.swift in Sources */,
3499551529232533007AB99E /* UIColor+.swift in Sources */,
342830F8292E1B7400AE811B /* PlainField.swift in Sources */,
34A529DA29247B9C001BAD34 /* AppDIContainer.swift in Sources */,
340A724B29348C2200B26AA6 /* DefaultAuthUseCase.swift in Sources */,
A50DE906292B53D900E1FD60 /* DefaultQuestsRepository.swift in Sources */,
34ACC32D291DE9C000741371 /* AppDelegate.swift in Sources */,
A5AC96D929223648003B7637 /* RealmStorage.swift in Sources */,
Expand All @@ -1065,6 +1092,7 @@
3416FC88292B54DB00B504C5 /* QuestUseCase.swift in Sources */,
A51F01D029233C510031ECA2 /* UserInfoEntity+Mapping.swift in Sources */,
3499552B29236041007AB99E /* BrowseViewModel.swift in Sources */,
34113BED2934BD3D00AB4919 /* TextFieldForm.swift in Sources */,
3449AD5B2922164B00B87619 /* Quest.swift in Sources */,
34283101292E2D7A00AE811B /* ToggleItemViewModel.swift in Sources */,
A5AC96E829223F27003B7637 /* RealmQuestsStorage.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// DefaultAuthUseCase.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/28.
//

import Foundation

import RxSwift

final class DefaultAuthUseCase {
private let authRepository: AuthRepository

init(authRepository: AuthRepository) {
self.authRepository = authRepository
}
}

extension DefaultAuthUseCase: AuthUseCase {
func signIn(email: String, password: String) -> Observable<Bool> {
return authRepository
.signIn(email: email, password: password)
.catch { _ in
return .just(false)
}
.asObservable()
}

func signOut() -> Observable<Bool> {
return authRepository
.signOut()
.catch { _ in
return .just(false)
}
.asObservable()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// AuthUseCase.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/28.
//

import Foundation

import RxSwift

protocol AuthUseCase {
func signIn(email: String, password: String) -> Observable<Bool>
func signOut() -> Observable<Bool>
}
35 changes: 35 additions & 0 deletions DailyQuest/DailyQuest/Presentation/Common/TextFieldForm.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// TextFieldForm.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/28.
//

import UIKit

final class TextFieldForm: UITextField {
var textPadding = UIEdgeInsets(top: 10, left: 20, bottom: 10, right: 20)

override init(frame: CGRect) {
super.init(frame: frame)
layer.borderWidth = 1
layer.borderColor = UIColor.maxYellow.cgColor
layer.cornerRadius = 5
backgroundColor = UIColor(named: "White")
textColor = .maxViolet
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func textRect(forBounds bounds: CGRect) -> CGRect {
let rect = super.textRect(forBounds: bounds)
return rect.inset(by: textPadding)
}

override func editingRect(forBounds bounds: CGRect) -> CGRect {
let rect = super.editingRect(forBounds: bounds)
return rect.inset(by: textPadding)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@

import UIKit

import RxSwift

protocol SettingsCoordinator: Coordinator {
func showLoginOutFlow()
func showLoginFlow()
}

final class DefaultSettingsCoordinator: SettingsCoordinator {
private var disposableBag = DisposeBag()

var finishDelegate: CoordinatorFinishDelegate?
var childCoordinators: [Coordinator] = []
var navigationController: UINavigationController
Expand All @@ -26,11 +30,20 @@ final class DefaultSettingsCoordinator: SettingsCoordinator {
func start() {
let settingsController = SettingsViewController()
navigationController.pushViewController(settingsController, animated: false)

settingsController
.itemDidClick
.bind(onNext: { [weak self] event in
switch event {
case .showLoginFlow:
self?.showLoginFlow()
}
})
.disposed(by: disposableBag)
}

func showLoginOutFlow() {
/**
Show Login view
*/
func showLoginFlow() {
let loginViewController = LoginViewController()
navigationController.pushViewController(loginViewController, animated: true)
}
}
11 changes: 11 additions & 0 deletions DailyQuest/DailyQuest/Presentation/Settings/View/CommonField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,18 @@

import UIKit

enum ViewType {
case login
}

protocol CommonField {
func register(for tableView: UITableView)
func dequeue(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell
func didSelect() -> ViewType?
}

extension CommonField {
func didSelect() -> ViewType? {
return nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@ extension NavigateField: CommonField {

return cell
}

func didSelect() -> ViewType? {
return viewModel.viewType
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ import Foundation
struct NavigateItemViewModel {
let title: String
let imageName: String
let viewType: ViewType
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// LoginViewController.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/28.
//

import UIKit

import RxSwift
import RxCocoa
import SnapKit

final class LoginViewController: UIViewController {

private lazy var container: UIStackView = {
let container = UIStackView()
container.axis = .vertical
container.spacing = 10

return container
}()

private lazy var emailField: TextFieldForm = {
let emailField = TextFieldForm()
emailField.placeholder = "email"

return emailField
}()

private lazy var passwordField: TextFieldForm = {
let passwordField = TextFieldForm()
passwordField.placeholder = "password"

return passwordField
}()

private lazy var submitButton: UIButton = {
var config = UIButton.Configuration.filled()
config.baseBackgroundColor = .maxYellow
config.title = "๋กœ๊ทธ์ธ"

return UIButton(configuration: config)
}()

// MARK: Life Cycle
override func viewDidLoad() {
super.viewDidLoad()

configureUI()
}

private func configureUI() {
view.backgroundColor = .white

container.addArrangedSubview(emailField)
container.addArrangedSubview(passwordField)
container.addArrangedSubview(submitButton)

view.addSubview(container)

container.snp.makeConstraints { make in
make.center.equalToSuperview()
make.width.equalToSuperview().multipliedBy(0.8)
}
}
}

#if canImport(SwiftUI) && DEBUG
import SwiftUI

struct ViewController_Preview: PreviewProvider {
static var previews: some View {
LoginViewController().showPreview(.iPhone14)
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@

import UIKit

import RxSwift
import RxCocoa

final class SettingsViewController: UITableViewController {
enum Event {
case showLoginFlow
}

var itemDidClick = PublishSubject<Event>()

private let fields: [CommonField] = [
ToggleField(viewModel: .init(title: "๋‘˜๋Ÿฌ๋ณด๊ธฐ ํ—ˆ์šฉ", imageName: "person.crop.circle.badge.checkmark")),
PlainField(viewModel: .init(title: "some", info: "some...?", imageName: "pencil")),
NavigateField(viewModel: .init(title: "๋กœ๊ทธ์ธ", imageName: "person.circle.fill")),
NavigateField(viewModel: .init(title: "๋กœ๊ทธ์ธ", imageName: "person.circle.fill", viewType: .login)),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ทธ ์–ด์ฐจํ”ผ ๊ณ ์ •์ ์ธ ํ•„๋“œ๋“ค์ด๋‹ˆ enum์œผ๋กœ ๊ด€๋ฆฌํ•ด๋„ ๊ดœ์ฐฎ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

PlainField(viewModel: .init(title: "์•ฑ ๋ฒ„์ „", info: "0.0.1", imageName: "exclamationmark.transmission"))
]

Expand All @@ -33,6 +41,16 @@ final class SettingsViewController: UITableViewController {
return field.dequeue(for: tableView, at: indexPath)
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let field = fields[indexPath.row]
guard let type = field.didSelect() else { return }

switch type {
case .login:
itemDidClick.onNext(.showLoginFlow)
}
}

private func register() {
fields.forEach { field in
field.register(for: self.tableView)
Expand Down
Loading