Skip to content

Commit

Permalink
✨ Feat: #40 - 재전송 버튼 누를 시, sendCertifyCode 재호출 및 타이머 초기화
Browse files Browse the repository at this point in the history
  • Loading branch information
usa4060 committed Nov 25, 2023
1 parent e5fb6b0 commit a192051
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 19 deletions.
20 changes: 20 additions & 0 deletions CMC/Sources/Data/Repositories/Auth/FakeAuthRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,24 @@ final class FakeAuthRepository: AuthRepository {
)
return Single.just(fakeSendCertifyCodeDTO)
}

func confirmCertifyCode(body: ConfirmCertifyCodeBody) -> Single<ConfirmCertifyCodeDTO> {
let fakeConfirmCertifyCodeDTO = ConfirmCertifyCodeDTO(
isSuccess: true,
code: "200",
message: "성공",
result: "인증번호가 발송되었습니다."
)
return Single.just(fakeConfirmCertifyCodeDTO)
}

func reSettingPassword(body: ResettingPasswordBody) -> Single<ResettingPasswordDTO> {
let fakeResettingPasswordDTO = ResettingPasswordDTO(
isSuccess: true,
code: "200",
message: "성공",
result: "인증번호가 발송되었습니다."
)
return Single.just(fakeResettingPasswordDTO)
}
}
1 change: 1 addition & 0 deletions CMC/Sources/Domain/Usecases/Auth/AuthUsecase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ protocol AuthUsecase {
func signUp(body: SignUpBody) -> Single<SignUpModel>
func signIn(body: SignInBody) -> Single<SignInModel>
func emailDup(query: EmailDupQuery) -> Single<EmailDupModel>
func sendCertifyCode(query: SendCertifyCodeQuery) -> Single<SendCertifyCodeModel>
func confirmCertifyCode(body: ConfirmCertifyCodeBody) -> Single<ConfirmCertifyCodeModel>
func reSettingPassword(body: ResettingPasswordBody) -> Single<ResettingPasswordModel>
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ final class ConfirmCertifyCodeView: BaseView {
return textField
}()

private lazy var confirmCertifyCodeButton: CMCButton = {
let button = CMCButton(
isRound: false,
iconTitle: nil,
type: .login(.disabled),
title: "인증번호 확인"
)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

// MARK: - Properties
private var viewModel: ConfirmCertifyCodeViewModel
Expand Down Expand Up @@ -79,6 +89,7 @@ final class ConfirmCertifyCodeView: BaseView {
addSubview(titleLabel)
addSubview(subTitle)
addSubview(certifyCodeTextField)
addSubview(confirmCertifyCodeButton)
}

override func setConstraint() {
Expand All @@ -100,6 +111,11 @@ final class ConfirmCertifyCodeView: BaseView {
$0.height.equalTo(74)
}

confirmCertifyCodeButton.snp.makeConstraints{ confirmCertifyCodeButton in
confirmCertifyCodeButton.leading.trailing.equalToSuperview().inset(20)
confirmCertifyCodeButton.bottom.equalTo(self.keyboardLayoutGuide.snp.top).offset(-20)
confirmCertifyCodeButton.height.equalTo(56)
}
}

override func bind() {
Expand All @@ -116,19 +132,39 @@ final class ConfirmCertifyCodeView: BaseView {
.disposed(by: disposeBag)


parentViewModel.timerStart
.withUnretained(self)
.subscribe(onNext: { owner, _ in
owner.certifyCodeTextField.resetTimer()
})
.disposed(by: disposeBag)

let input = ConfirmCertifyCodeViewModel.Input(
nowPage: parentViewModel.nowPage.asObservable(),
email: parentViewModel.email.asObservable(),
certifiedCode: certifyCodeTextField.rx.text.orEmpty.asObservable(),
reSendButtonTapped: certifyCodeTextField.accessoryCMCButton.rx.tap.asObservable()
)

let output = viewModel.transform(input: input)

output.startTimer
.withUnretained(self)
.subscribe(onNext: { owner, isStart in
if isStart {
owner.certifyCodeTextField.resetTimer()
output.sendCertifyResult
.observe(on: MainScheduler.instance)
.subscribe(onNext: { [weak self] isSuccessed in
guard let ss = self else { return }
if isSuccessed {
ss.parentViewModel.nowPage.accept(2)
ss.parentViewModel.timerStart.accept(())
CMCBottomSheetManager.shared.showBottomSheet(
title: "인증번호를 전송했어요",
body: "3분 내 인증번호를 입력해주세요 :)",
buttonTitle: "확인"
)
} else {
CMCBottomSheetManager.shared.showBottomSheet(
title: "존재하지 않는 계정이에요",
body: "아이디 찾기는 운영진에게 문의해주세요 :)",
buttonTitle: "확인"
)
}
})
.disposed(by: disposeBag)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,19 @@ import RxSwift
final class ConfirmCertifyCodeViewModel: ViewModelType {

struct Input {
let nowPage: Observable<Int>
let email: Observable<String>
let certifiedCode: Observable<String>
let reSendButtonTapped: Observable<Void>
}

struct Output {
let startTimer: Observable<Bool>
let sendCertifyResult: Observable<Bool>
let nextAvailable: Observable<Bool>
}

var disposeBag: DisposeBag = DisposeBag()
private let usecase: AuthUsecase

private let startTimer = BehaviorRelay<Bool>(value: false)
private let nextAvailable = BehaviorRelay<Bool>(value: false)

init(
Expand All @@ -41,24 +40,31 @@ final class ConfirmCertifyCodeViewModel: ViewModelType {

func transform(input: Input) -> Output {

input.nowPage
.withUnretained(self)
.subscribe(onNext: { owner, page in
if page == 2 {
owner.startTimer.accept(true)
}
})
.disposed(by: disposeBag)

input.certifiedCode
.withUnretained(self)
.subscribe(onNext: { owner, code in
code.count >= 6 ? owner.nextAvailable.accept(true) : owner.nextAvailable.accept(false)
})
.disposed(by: disposeBag)


let sendCertifyResult = input.reSendButtonTapped
.withLatestFrom(input.email)
.withUnretained(self)
.flatMapLatest { owner, email -> Observable<Bool> in
let query = SendCertifyCodeQuery(email: email)
return owner.usecase.sendCertifyCode(query: query)
.asObservable()
.map { _ in true}
.catch { _ in
return .just(false)
}
}
.share()


return Output(
startTimer: startTimer.asObservable(),
sendCertifyResult: sendCertifyResult,
nextAvailable: nextAvailable.asObservable()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ final class SendCertifyCodeView: BaseView {
})
.disposed(by: disposeBag)

self.emailTextField.rx.text.orEmpty
.bind(to: parentViewModel.email)
.disposed(by: disposeBag)

let input = SendCertifyCodeViewModel.Input(
email: emailTextField.rx.text.orEmpty.asObservable(),
receiveCertifyTapped: receiveCertiftyButton.rx.tap.asObservable()
Expand All @@ -153,6 +157,7 @@ final class SendCertifyCodeView: BaseView {
guard let ss = self else { return }
if isSuccessed {
ss.parentViewModel.nowPage.accept(2)
ss.parentViewModel.timerStart.accept(())
CMCBottomSheetManager.shared.showBottomSheet(
title: "인증번호를 전송했어요",
body: "3분 내 인증번호를 입력해주세요 :)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class FindPasswordViewModel: ViewModelType{

let email = BehaviorRelay<String>(value: "")
let nowPage = BehaviorRelay<Int>(value: 1)
let timerStart = PublishRelay<Void>()

// MARK: - Initializers
init(
Expand Down
1 change: 1 addition & 0 deletions DesignSystem/Sources/CMCTextField+Timer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ public final class CMCTextField_Timer: UIView {
}

public func resetTimer() {
timerDisposeBag = DisposeBag() // 타이머 구독 해제
timerCountRelay.accept(180) // 초기 시간을 180초로 설정
startTimer() // 타이머 다시 시작
}
Expand Down

0 comments on commit a192051

Please sign in to comment.