214 lines
7.6 KiB
Swift
214 lines
7.6 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
|
|
self?.viewModel.performWechatLogin()
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
rootView.appleLoginBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] in
|
|
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
|
|
}
|
|
GeYanSdk.preGetToken { preDic in
|
|
guard let dict = preDic as? [String: Any],
|
|
dict["code"] as? Int == 30000,
|
|
let model = GyContentModel.current(),
|
|
!model.pn.isEmpty else {
|
|
DLToast.showError(text: "获取手机号失败,请使用验证码登录")
|
|
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 登录失败")
|
|
}
|
|
}
|