231 lines
8.4 KiB
Swift
231 lines
8.4 KiB
Swift
//
|
||
// LoginViewController.swift
|
||
// QuickLocation
|
||
//
|
||
// Created based on Lanhu design: 登录-一键登录
|
||
//
|
||
|
||
import UIKit
|
||
import SnapKit
|
||
import RxSwift
|
||
import RxCocoa
|
||
import AuthenticationServices
|
||
#if !targetEnvironment(simulator)
|
||
import GeYanSdk
|
||
#endif
|
||
|
||
class LoginViewController: BaseViewController {
|
||
|
||
override var isNavigationBarHidden: Bool { true }
|
||
override var preferredStatusBarStyle: UIStatusBarStyle { .default }
|
||
|
||
// MARK: - Properties
|
||
fileprivate var rootView: LoginView!
|
||
|
||
private let viewModel = LoginViewModel()
|
||
private var isAgreed = false
|
||
private var countDownService = CountDownService(countDownTime: 60)
|
||
|
||
|
||
|
||
// MARK: - Lifecycle
|
||
override func loadView() {
|
||
rootView = LoginView(frame: UIScreen.main.bounds)
|
||
view = rootView
|
||
}
|
||
|
||
override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
rootView.agreementTV.delegate = self
|
||
bindViewModel()
|
||
reactiveAction()
|
||
}
|
||
|
||
private func reactiveAction() {
|
||
rootView.smsCodeBtn.rx.controlEvent(.touchUpInside).subscribe { [weak self] _ in
|
||
guard let self = self else { return }
|
||
self.requestSmsCodeAPI()
|
||
}.disposed(by: rootView.disposeBag)
|
||
}
|
||
|
||
// MARK: - Bindings
|
||
private func bindViewModel() {
|
||
rootView.checkBox.rx.tap
|
||
.subscribe(onNext: { [weak self] in
|
||
self?.isAgreed.toggle()
|
||
self?.rootView.checkBox.isSelected = self?.isAgreed ?? false
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
rootView.loginButton.rx.tap
|
||
.subscribe(onNext: { [weak self] in
|
||
guard let self = self else { return }
|
||
|
||
if !self.isAgreed {
|
||
DLToast.showError(text: "请先同意用户协议")
|
||
return
|
||
}
|
||
|
||
guard let phone = self.rootView.phoneInputTF.text, !phone.isEmpty else {
|
||
DLToast.showError(text: "请输入手机号码")
|
||
return
|
||
}
|
||
|
||
guard let smsCode = self.rootView.smsCodeTF.text, !smsCode.isEmpty else {
|
||
DLToast.showError(text: "请输入验证码")
|
||
return
|
||
}
|
||
|
||
let requestData = ["timestamp": self.viewModel.timestamp,
|
||
"phone": phone,
|
||
"code": smsCode]
|
||
self.viewModel.loginAction(type: "phone", data: requestData)
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
rootView.guestLoginButton.rx.tap
|
||
.subscribe(onNext: { _ in
|
||
AppDelegate.shared.showMainViewController()
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
rootView.wechatLoginBtn.rx.tap
|
||
.subscribe(onNext: { [weak self] in
|
||
guard self?.isAgreed == true else {
|
||
DLToast.showError(text: "请先同意用户协议")
|
||
return
|
||
}
|
||
self?.viewModel.performWechatLogin()
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
rootView.appleLoginBtn.rx.tap
|
||
.subscribe(onNext: { [weak self] in
|
||
guard self?.isAgreed == true else {
|
||
DLToast.showError(text: "请先同意用户协议")
|
||
return
|
||
}
|
||
self?.viewModel.performAppleLogin()
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
viewModel.onAppleLoginRequest = { [weak self] controller in
|
||
guard let self = self else { return }
|
||
controller.delegate = self
|
||
controller.presentationContextProvider = self
|
||
controller.performRequests()
|
||
}
|
||
|
||
rootView.phoneLoginBtn.rx.tap
|
||
.subscribe(onNext: { [weak self] in
|
||
#if !targetEnvironment(simulator)
|
||
if GeYanSdk.getCurrentCarrierCount() == 0 {
|
||
DLToast.show(text: "请插入SIM卡后重试")
|
||
return
|
||
}
|
||
|
||
if GeYanSdk.isPreGettedTokenValidate() { //预登录有效,启动登录授权页
|
||
let oneTapView = OneTapLoginView(frame: UIScreen.main.bounds)
|
||
self?.viewModel.performOneTapLogin(from: self!, contentView: oneTapView)
|
||
return
|
||
}
|
||
|
||
// 预登录
|
||
GeYanSdk.preGetToken { preDic in
|
||
guard GeYanSdk.isPreGettedTokenValidate() else {
|
||
var message = ""
|
||
if let dict = preDic as? [String: Any] {
|
||
message = dict["msg"] as? String ?? "获取手机号失败,请使用验证码登录"
|
||
}
|
||
DLToast.show(text: message)
|
||
return
|
||
}
|
||
let oneTapView = OneTapLoginView(frame: UIScreen.main.bounds)
|
||
self?.viewModel.performOneTapLogin(from: self!, contentView: oneTapView)
|
||
}
|
||
#endif
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
// viewModel.loginSuccess
|
||
// .subscribe(onNext: { [weak self] in
|
||
//
|
||
// })
|
||
// .disposed(by: disposeBag)
|
||
}
|
||
|
||
// MARK: - API 验证码
|
||
func requestSmsCodeAPI() {
|
||
DLToast.showLoading()
|
||
SystemService.sendSmsCode(phone: rootView.phoneInputTF.text ?? "").subscribe(onNext: { [weak self] response in
|
||
DLToast.showSuccess(text: "发送成功")
|
||
guard let self = self, let responseData = response.result as? [String : Any] else { return }
|
||
self.startCountDown(self.rootView.smsCodeBtn, self.countDownService)
|
||
if let timestamp = responseData["timestamp"] as? String {
|
||
self.viewModel.timestamp = timestamp
|
||
}
|
||
}, onError: { _ in }).disposed(by: disposeBag)
|
||
}
|
||
}
|
||
|
||
extension LoginViewController: UITextViewDelegate {
|
||
func textView(_ textView: UITextView,
|
||
shouldInteractWith URL: URL,
|
||
in characterRange: NSRange,
|
||
interaction: UITextItemInteraction) -> Bool {
|
||
// if URL.absoluteString == "Carrier", let model = GyContentModel.current(), let link = model.link {
|
||
// AppRouter.push(Route.web, userInfo: ["url": link])
|
||
// }
|
||
if URL.absoluteString == "UserAgreement" {
|
||
AppRouter.push(Route.web, userInfo: ["url": URLManager.shared.userAgreementUrl])
|
||
}
|
||
if URL.absoluteString == "PrivacyPolicy" {
|
||
AppRouter.push(Route.web, userInfo: ["url": URLManager.shared.privacyPolicyUrl])
|
||
}
|
||
return true
|
||
}
|
||
|
||
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
|
||
false
|
||
}
|
||
|
||
private func openURL(_ url: String) {}
|
||
}
|
||
|
||
// MARK: - Apple Sign In
|
||
extension LoginViewController: ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
||
|
||
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
||
view.window ?? UIWindow()
|
||
}
|
||
|
||
func authorizationController(controller: ASAuthorizationController,
|
||
didCompleteWithAuthorization authorization: ASAuthorization) {
|
||
guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential else { return }
|
||
|
||
let userId = credential.user
|
||
let userName: String = {
|
||
if let name = credential.fullName {
|
||
let parts = [name.givenName, name.familyName].compactMap { $0 }
|
||
if !parts.isEmpty { return parts.joined(separator: " ") }
|
||
}
|
||
return ""
|
||
}()
|
||
let identityToken = credential.identityToken.flatMap { String(data: $0, encoding: .utf8) } ?? ""
|
||
let authCode = credential.authorizationCode.flatMap { String(data: $0, encoding: .utf8) } ?? ""
|
||
|
||
viewModel.loginAction(type: "apple", data: [
|
||
"user_id": userId,
|
||
"user_name": userName,
|
||
"identify_code": authCode,
|
||
"identify_token": identityToken
|
||
])
|
||
}
|
||
|
||
func authorizationController(controller: ASAuthorizationController,
|
||
didCompleteWithError error: Error) {
|
||
NotificationCenter.default.post(name: .resumePopupQueue, object: nil)
|
||
DLToast.showError(text: "Apple 登录失败")
|
||
}
|
||
}
|