|
@@ -5,9 +5,326 @@
|
|
|
// Created by ak on 2021/6/2.
|
|
|
//
|
|
|
|
|
|
-import Foundation
|
|
|
-class MVLoginController: MVBaseController{
|
|
|
+import AuthenticationServices
|
|
|
+import JWTDecode
|
|
|
+import UIKit
|
|
|
+import BFFramework
|
|
|
+import TYAttributedLabel
|
|
|
|
|
|
+class MVLoginController: MVBaseController {
|
|
|
+ let nomalH: CGFloat = cDefaultMargin * 5
|
|
|
|
|
|
+ @available(iOS 13.0, *)
|
|
|
+ lazy var appleSignBtn: ASAuthorizationAppleIDButton = {
|
|
|
+ let appleSignBtn: ASAuthorizationAppleIDButton = ASAuthorizationAppleIDButton(type: .signIn, style: .white)
|
|
|
+ appleSignBtn.cornerRadius = nomalH / 2
|
|
|
+ // appleSignBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#333333")
|
|
|
+ appleSignBtn.isHidden = true
|
|
|
+ appleSignBtn.frame = CGRect(x: 0, y: 0, width: nomalH, height: nomalH)
|
|
|
+ appleSignBtn.center = view.center
|
|
|
+ appleSignBtn.addTarget(self, action: #selector(appleLoginAction), for: .touchUpInside)
|
|
|
+ return appleSignBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var protocolLab: TYAttributedLabel = {
|
|
|
+ let protocolLab = TYAttributedLabel()
|
|
|
+ protocolLab.highlightedLinkBackgroundColor = UIColor.black
|
|
|
+ protocolLab.backgroundColor = UIColor.white
|
|
|
+ protocolLab.delegate = self
|
|
|
+ protocolLab.numberOfLines = 0
|
|
|
+ protocolLab.font = UIFont.systemFont(ofSize: 12)
|
|
|
+ protocolLab.textAlignment = CTTextAlignment.center
|
|
|
+ return protocolLab
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var loginBtn: UIButton = {
|
|
|
+ let loginBtn = UIButton(type: .custom)
|
|
|
+ loginBtn.addTarget(self, action: #selector(wechatLoginAction), for: .touchUpInside)
|
|
|
+ loginBtn.setTitleColor(UIColor.white, for: .normal)
|
|
|
+ loginBtn.setTitle(" 微信登录", for: .normal)
|
|
|
+ loginBtn.titleEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 0)
|
|
|
+ loginBtn.titleLabel?.font = UIFont.systemFont(ofSize: 15)
|
|
|
+ loginBtn.setImage(UIImage(named: "weichatLogin"), for: .normal)
|
|
|
+ loginBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#07C160")
|
|
|
+ loginBtn.addCorner(corner: nomalH / 2)
|
|
|
+ return loginBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var phoneLoginBtn: UIButton = {
|
|
|
+ let phoneLoginBtn = UIButton(type: .custom)
|
|
|
+ phoneLoginBtn.addTarget(self, action: #selector(phoneLoginAction), for: .touchUpInside)
|
|
|
+ phoneLoginBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#07C160"), for: .normal)
|
|
|
+ phoneLoginBtn.setTitle(" 手机号登录", for: .normal)
|
|
|
+ phoneLoginBtn.titleEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 0)
|
|
|
+
|
|
|
+ phoneLoginBtn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
|
|
|
+ phoneLoginBtn.setImage(UIImage(named: "icon_phone"), for: .normal)
|
|
|
+ phoneLoginBtn.backgroundColor = UIColor.white
|
|
|
+ phoneLoginBtn.addCorner(corner: nomalH / 2)
|
|
|
+ return phoneLoginBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+ //icon
|
|
|
+ lazy var IconView: UIImageView = {
|
|
|
+ let IconView = UIImageView.init(image: UIImage(named: "1024x1024px"))
|
|
|
+
|
|
|
+ return IconView
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var remindBtn: UIButton = {
|
|
|
+ let remindBtn = UIButton(type: .custom)
|
|
|
+ remindBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#333333")
|
|
|
+ remindBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#999999"), for: .normal)
|
|
|
+ remindBtn.titleLabel?.font = UIFont.systemFont(ofSize: 13)
|
|
|
+ remindBtn.setTitle(remindTitle, for: .normal)
|
|
|
+ remindBtn.addCorner(corner: 12)
|
|
|
+ return remindBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+ var remindTitle: String? {
|
|
|
+ didSet {
|
|
|
+ remindBtn.setTitle(" \(remindTitle ?? "登录") ", for: .normal)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override func viewDidLoad() {
|
|
|
+ super.viewDidLoad()
|
|
|
+ view.addSubview(IconView)
|
|
|
+ view.addSubview(remindBtn)
|
|
|
+
|
|
|
+ remindBtn.isHidden = !(remindTitle != nil && remindTitle?.count ?? 0 > 0)
|
|
|
+ // 请求配置
|
|
|
+ PQBaseViewModel.systemConfig { [weak self] _ in
|
|
|
+ self?.view.addSubview(self!.loginBtn)
|
|
|
+ self?.view.addSubview(self!.phoneLoginBtn)
|
|
|
+ self?.view.addSubview(self!.protocolLab)
|
|
|
+ if PQSingletoMemoryUtil.shared.needLogin {
|
|
|
+ if #available(iOS 13.0, *) {
|
|
|
+ self?.view.addSubview(self!.appleSignBtn)
|
|
|
+ self?.appleSignBtn.isHidden = false
|
|
|
+ self?.loginBtn.setTitle(nil, for: .normal)
|
|
|
+ self?.phoneLoginBtn.setTitle(nil, for: .normal)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ self?.addLayout()
|
|
|
+ self?.phoneLoginBtn.isHidden = !PQSingletoMemoryUtil.shared.needLogin
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override func viewWillAppear(_: Bool) {
|
|
|
+ super.viewWillAppear(true)
|
|
|
+
|
|
|
+ showNavigation()
|
|
|
+ leftButton(image: "close")
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ override public func viewWillDisappear(_: Bool) {
|
|
|
+ super.viewWillDisappear(true)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ func addLayout() {
|
|
|
+ protocolLab.snp.makeConstraints { make in
|
|
|
+ make.bottom.equalTo(view).offset(-cDefaultMargin * 5)
|
|
|
+ make.left.equalTo(view).offset(cDefaultMargin * 2)
|
|
|
+ make.right.equalTo(view).offset(-cDefaultMargin * 2)
|
|
|
+ make.height.equalTo(cScreenHeigth <= 568 ? cDefaultMargin * 4 : cDefaultMargin * 6)
|
|
|
+ }
|
|
|
+ IconView.snp.makeConstraints { make in
|
|
|
+ make.top.equalTo(view).offset(241)
|
|
|
+ make.centerX.equalTo(view)
|
|
|
+ make.height.width.equalTo(260)
|
|
|
+ }
|
|
|
+ remindBtn.snp.makeConstraints { make in
|
|
|
+// make.width.equalTo(cDefaultMargin * 13)
|
|
|
+ make.height.equalTo(cDefaultMargin * 4)
|
|
|
+ make.centerX.equalTo(IconView)
|
|
|
+ make.top.equalTo(IconView.snp_bottom).offset(cDefaultMargin * 4)
|
|
|
+ }
|
|
|
+ let isInstallWX = PQSingletoWXApiUtil.shared.isInstallWX()
|
|
|
+
|
|
|
+ if PQSingletoMemoryUtil.shared.needLogin {
|
|
|
+ if #available(iOS 13.0, *) {
|
|
|
+ if isInstallWX {
|
|
|
+ loginBtn.snp.makeConstraints { make in
|
|
|
+ make.centerX.equalToSuperview()
|
|
|
+ make.height.width.equalTo(nomalH)
|
|
|
+ make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
|
|
|
+ }
|
|
|
+ phoneLoginBtn.snp.makeConstraints { make in
|
|
|
+ make.left.equalTo(loginBtn.snp_right).offset(cDefaultMargin * 4)
|
|
|
+ make.height.centerY.width.equalTo(loginBtn)
|
|
|
+ }
|
|
|
+ appleSignBtn.snp.makeConstraints { make in
|
|
|
+ make.right.equalTo(loginBtn.snp_left).offset(-cDefaultMargin * 4)
|
|
|
+ make.height.centerY.width.equalTo(loginBtn)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ appleSignBtn.snp.makeConstraints { make in
|
|
|
+ make.centerX.equalToSuperview().offset(-35)
|
|
|
+ make.height.width.equalTo(nomalH)
|
|
|
+ make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
|
|
|
+ }
|
|
|
+ phoneLoginBtn.snp.makeConstraints { make in
|
|
|
+ make.left.equalTo(appleSignBtn.snp_right).offset(cDefaultMargin * 4)
|
|
|
+ make.height.centerY.width.equalTo(appleSignBtn)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if isInstallWX {
|
|
|
+ loginBtn.snp.makeConstraints { make in
|
|
|
+ make.left.right.equalTo(protocolLab)
|
|
|
+ make.height.equalTo(nomalH)
|
|
|
+ make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
|
|
|
+ }
|
|
|
+ phoneLoginBtn.snp.makeConstraints { make in
|
|
|
+ make.left.right.equalTo(protocolLab)
|
|
|
+ make.height.equalTo(nomalH)
|
|
|
+ make.bottom.equalTo(loginBtn.snp_top).offset(-cDefaultMargin)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ phoneLoginBtn.snp.makeConstraints { make in
|
|
|
+ make.left.right.equalTo(protocolLab)
|
|
|
+ make.height.equalTo(nomalH)
|
|
|
+ make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ loginBtn.snp.makeConstraints { make in
|
|
|
+ make.left.right.equalTo(protocolLab)
|
|
|
+ make.height.equalTo(nomalH)
|
|
|
+ make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+extension MVLoginController: TYAttributedLabelDelegate {
|
|
|
+ func attributedLabel(_: TYAttributedLabel!, textStorageClicked textStorage: TYTextStorageProtocol!, at _: CGPoint) {
|
|
|
+ var link: String? = (textStorage as? TYLinkTextStorage)?.linkData as? String ?? ""
|
|
|
+ if link == nil || (link?.count ?? 0) <= 0 {
|
|
|
+ let range = (textStorage as? TYLinkTextStorage)?.range
|
|
|
+ if range?.length == 11 {
|
|
|
+ link = cUserProtocol
|
|
|
+ } else if range?.length == 6 {
|
|
|
+ link = cPrivacy
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let detail = PQBaseWebViewController()
|
|
|
+ detail.baseUrl = link
|
|
|
+ navigationController?.pushViewController(detail, animated: true)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+extension MVLoginController: ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
|
|
+ @objc func wechatLoginAction() {
|
|
|
+ PQSingletoWXApiUtil.shared.authorize().wxApiUtilHander = { [weak self] userData, errorMsg in
|
|
|
+ if userData == nil {
|
|
|
+ // cShowHUB(superView:nil, msg: errorMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ PQMineViewModel.wechatLogin(unionid: "\(userData?["unionid"] ?? "")", openId: "\(userData?["openid"] ?? "")", nickName: "\(userData?["nickname"] ?? "")", avatarUrl: "\(userData?["headimgurl"] ?? "")") { [weak self] _, errorMsg in
|
|
|
+ if errorMsg != nil {
|
|
|
+ cShowHUB(superView: nil, msg: "登录失败,请重试~")
|
|
|
+ } else {
|
|
|
+ cShowHUB(superView: nil, msg: "登录成功")
|
|
|
+ self?.navigationController?.popViewController(animated: true)
|
|
|
+ postNotification(name: cLoginSuccesssNotiKey)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func phoneLoginAction() {
|
|
|
+ let vc = PQPhoneLoginController()
|
|
|
+ navigationController?.pushViewController(vc, animated: true)
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func appleLoginAction() {
|
|
|
+ if #available(iOS 13.0, *) {
|
|
|
+ let appleIDProvider = ASAuthorizationAppleIDProvider()
|
|
|
+ let appleRequest = appleIDProvider.createRequest()
|
|
|
+ appleRequest.requestedScopes = [.fullName, .email]
|
|
|
+ let auth = ASAuthorizationController(authorizationRequests: [appleRequest])
|
|
|
+ auth.delegate = self
|
|
|
+ auth.presentationContextProvider = self
|
|
|
+ auth.performRequests()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Apple登录回调
|
|
|
+
|
|
|
+ @available(iOS 13.0, *)
|
|
|
+ func presentationAnchor(for _: ASAuthorizationController) -> ASPresentationAnchor {
|
|
|
+ return view.window!
|
|
|
+ }
|
|
|
+
|
|
|
+ @available(iOS 13.0, *)
|
|
|
+ func authorizationController(controller _: ASAuthorizationController, didCompleteWithError error: Error) {
|
|
|
+ BFLog(message: "didCompleteWithError - \(error)")
|
|
|
+ switch (error as NSError).code {
|
|
|
+ case ASAuthorizationError.canceled.rawValue:
|
|
|
+ cShowHUB(superView: nil, msg: "你取消了授权登录")
|
|
|
+ case ASAuthorizationError.failed.rawValue:
|
|
|
+ cShowHUB(superView: nil, msg: "授权失败,请重新登录")
|
|
|
+ case ASAuthorizationError.invalidResponse.rawValue:
|
|
|
+ cShowHUB(superView: nil, msg: "暂时无响应哦,请重新登录")
|
|
|
+ case ASAuthorizationError.notHandled.rawValue:
|
|
|
+ cShowHUB(superView: nil, msg: "暂时无响应哦,请重新登录")
|
|
|
+ case ASAuthorizationError.unknown.rawValue:
|
|
|
+ cShowHUB(superView: nil, msg: "暂时无响应哦,请重新登录")
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @available(iOS 13.0, *)
|
|
|
+ func authorizationController(controller _: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
|
|
+ if authorization.credential.isKind(of: ASAuthorizationAppleIDCredential.self) {
|
|
|
+ let credential: ASAuthorizationAppleIDCredential = authorization.credential as! ASAuthorizationAppleIDCredential
|
|
|
+ let user = credential.user
|
|
|
+ let identityToken = credential.identityToken
|
|
|
+ let token = String(data: identityToken!, encoding: .utf8)
|
|
|
+ if valideToken(token: token, user: user) {
|
|
|
+ PQMineViewModel.appleLogin(token: token ?? "") { [weak self] _, errorMsg in
|
|
|
+ if errorMsg != nil {
|
|
|
+ cShowHUB(superView: nil, msg: errorMsg)
|
|
|
+ } else {
|
|
|
+ cShowHUB(superView: nil, msg: "登录成功")
|
|
|
+ self?.navigationController?.popViewController(animated: true)
|
|
|
+ postNotification(name: cLoginSuccesssNotiKey)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ cShowHUB(superView: nil, msg: "校验失败,请重新登录")
|
|
|
+ }
|
|
|
+ } else if authorization.credential.isKind(of: ASPasswordCredential.self) {
|
|
|
+ let credential: ASPasswordCredential = authorization.credential as! ASPasswordCredential
|
|
|
+ let user = credential.user
|
|
|
+ BFLog(message: "user = \(user)")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 本地校验
|
|
|
+ /// - Parameters:
|
|
|
+ /// - identityToken: <#identityToken description#>
|
|
|
+ /// - user: <#user description#>
|
|
|
+ /// - Returns: <#description#>
|
|
|
+ func valideToken(token: String?, user: String) -> Bool {
|
|
|
+ if token == nil || (token?.isEmpty ?? true) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ let jwt = try! decode(jwt: token!)
|
|
|
+ BFLog(message: "\(jwt)")
|
|
|
+ if jwt.body.keys.contains("sub") {
|
|
|
+ let sub: String = jwt.body["sub"] as! String
|
|
|
+ if sub == user { // 校验成功
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+}
|