登录页面,反馈首页

This commit is contained in:
zeng 2025-04-25 15:42:52 +08:00
parent a7d98fb2f6
commit 21fd9c5c41
44 changed files with 604 additions and 59 deletions

View File

@ -7,6 +7,9 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1BCF943F2DBB62FB008AEBE9 /* FacebookBasics in Frameworks */ = {isa = PBXBuildFile; productRef = 1BCF943E2DBB62FB008AEBE9 /* FacebookBasics */; };
1BCF94412DBB62FB008AEBE9 /* FacebookCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1BCF94402DBB62FB008AEBE9 /* FacebookCore */; };
1BCF94432DBB62FB008AEBE9 /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 1BCF94422DBB62FB008AEBE9 /* FacebookLogin */; };
510C67DE404B0A4C9F4E89C3 /* Pods_Thimra.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF2D7FDB1FE86E5CD9908162 /* Pods_Thimra.framework */; }; 510C67DE404B0A4C9F4E89C3 /* Pods_Thimra.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF2D7FDB1FE86E5CD9908162 /* Pods_Thimra.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -43,7 +46,10 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
1BCF94432DBB62FB008AEBE9 /* FacebookLogin in Frameworks */,
510C67DE404B0A4C9F4E89C3 /* Pods_Thimra.framework in Frameworks */, 510C67DE404B0A4C9F4E89C3 /* Pods_Thimra.framework in Frameworks */,
1BCF94412DBB62FB008AEBE9 /* FacebookCore in Frameworks */,
1BCF943F2DBB62FB008AEBE9 /* FacebookBasics in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -134,6 +140,9 @@
); );
mainGroup = 1DBC40502DA4EDFC0093FCB0; mainGroup = 1DBC40502DA4EDFC0093FCB0;
minimizedProjectReferenceProxies = 1; minimizedProjectReferenceProxies = 1;
packageReferences = (
1BCF943D2DBB62FB008AEBE9 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */,
);
preferredProjectObjectVersion = 77; preferredProjectObjectVersion = 77;
productRefGroup = 1DBC405A2DA4EDFC0093FCB0 /* Products */; productRefGroup = 1DBC405A2DA4EDFC0093FCB0 /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -434,6 +443,35 @@
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
1BCF943D2DBB62FB008AEBE9 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/facebook/facebook-ios-sdk";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 14.1.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
1BCF943E2DBB62FB008AEBE9 /* FacebookBasics */ = {
isa = XCSwiftPackageProductDependency;
package = 1BCF943D2DBB62FB008AEBE9 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */;
productName = FacebookBasics;
};
1BCF94402DBB62FB008AEBE9 /* FacebookCore */ = {
isa = XCSwiftPackageProductDependency;
package = 1BCF943D2DBB62FB008AEBE9 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */;
productName = FacebookCore;
};
1BCF94422DBB62FB008AEBE9 /* FacebookLogin */ = {
isa = XCSwiftPackageProductDependency;
package = 1BCF943D2DBB62FB008AEBE9 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */;
productName = FacebookLogin;
};
/* End XCSwiftPackageProductDependency section */
}; };
rootObject = 1DBC40512DA4EDFC0093FCB0 /* Project object */; rootObject = 1DBC40512DA4EDFC0093FCB0 /* Project object */;
} }

View File

@ -0,0 +1,15 @@
{
"originHash" : "ca3cf5f8f83d297b47d2cb0edff3e06f294951e2e06fa55cfc82831103499b2a",
"pins" : [
{
"identity" : "facebook-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/facebook/facebook-ios-sdk",
"state" : {
"revision" : "c19607d535864533523d1f437c84035e5fb101cf",
"version" : "14.1.0"
}
}
],
"version" : 3
}

View File

@ -0,0 +1,28 @@
//
// AppDelegate+OpenApp.swift
// Thimra
//
// Created by on 2025/4/25.
//
import UIKit
extension SceneDelegate {
///URLAPP
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
}
///UniversalLink app
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
guard let webpageURL = userActivity.webpageURL else { return }
guard let query = webpageURL.query else { return }
spLog(message: query)
}
}

View File

@ -23,14 +23,14 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
private(set) var isViewDidLoad = false private(set) var isViewDidLoad = false
private(set) var isDidAppear = false private(set) var isDidAppear = false
private(set) lazy var _bgImageView: UIImageView = { private(set) lazy var bgImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "main_bg_image_01")) let imageView = UIImageView(image: UIImage(named: "main_bg_image_01"))
imageView.isUserInteractionEnabled = true imageView.isUserInteractionEnabled = true
return imageView; return imageView;
}() }()
/// ///
private lazy var toGradientView: SPGradientView = { private lazy var topGradientView: SPGradientView = {
let view = SPGradientView() let view = SPGradientView()
view.colors = [UIColor.color290D0F().cgColor, UIColor.color230E11().cgColor, UIColor.color181115().cgColor, UIColor.color121317(alpha: 0).cgColor] view.colors = [UIColor.color290D0F().cgColor, UIColor.color230E11().cgColor, UIColor.color181115().cgColor, UIColor.color121317(alpha: 0).cgColor]
view.startPoint = .init(x: 0.5, y: 0) view.startPoint = .init(x: 0.5, y: 0)
@ -44,8 +44,19 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
self.isViewDidLoad = true self.isViewDidLoad = true
self.edgesForExtendedLayout = [] self.edgesForExtendedLayout = []
view.addSubview(topGradientView)
view.addSubview(bgImageView)
setBgImageView() topGradientView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
make.height.equalTo(kSPStatusbarHeight + 420)
}
bgImageView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
}
setBackgroundView()
if let navi = navigationController { if let navi = navigationController {
if navi.visibleViewController == self { if navi.visibleViewController == self {
@ -56,15 +67,11 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
} }
} }
func setBgImageView() { func setBackgroundView(isShowGradient: Bool = true, bgImage: UIImage? = UIImage(named: "main_bg_image_01"), backgroundColor: UIColor = UIColor.backgroundColor()) {
self.view.backgroundColor = .backgroundColor() topGradientView.isHidden = !isShowGradient
bgImageView.isHidden = isShowGradient
self.view.addSubview(toGradientView) bgImageView.image = bgImage
view.backgroundColor = backgroundColor
toGradientView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
make.height.equalTo(kSPStatusbarHeight + 420)
}
} }
override func viewDidAppear(_ animated: Bool) { override func viewDidAppear(_ animated: Bool) {

View File

@ -0,0 +1,23 @@
//
// Dictionary+SPAdd.swift
// Thimra
//
// Created by on 2025/4/25.
//
import UIKit
extension Dictionary {
func toJsonString() -> String? {
do {
let data = try JSONSerialization.data(withJSONObject: self)
let jsonStr = String(data: data, encoding: .utf8)
return jsonStr
} catch {
}
return nil
}
}

View File

@ -20,7 +20,7 @@ extension String: SmartCodable {
static func timeZone() -> String { static func timeZone() -> String {
let timeZone = NSTimeZone.local as NSTimeZone let timeZone = NSTimeZone.local as NSTimeZone
let timeZoneAbbreviation = timeZone.name.length() > 0 ? timeZone.name : "Unknown" // let timeZoneAbbreviation = timeZone.name.length() > 0 ? timeZone.name : "Unknown"
let timeZoneSecondsFromGMT = timeZone.secondsFromGMT / 3600 let timeZoneSecondsFromGMT = timeZone.secondsFromGMT / 3600
return String(format: "GMT+0%d:00", timeZoneSecondsFromGMT) return String(format: "GMT+0%d:00", timeZoneSecondsFromGMT)
} }

View File

@ -192,5 +192,17 @@ extension UIColor {
static func colorE6334B(alpha: CGFloat = 1) -> UIColor { static func colorE6334B(alpha: CGFloat = 1) -> UIColor {
return color(hex: 0xE6334B, alpha: alpha) return color(hex: 0xE6334B, alpha: alpha)
} }
static func color0866FF(alpha: CGFloat = 1) -> UIColor {
return color(hex: 0x0866FF, alpha: alpha)
}
static func color333333(alpha: CGFloat = 1) -> UIColor {
return color(hex: 0x333333, alpha: alpha)
}
static func colorB0B0B3(alpha: CGFloat = 1) -> UIColor {
return color(hex: 0xB0B0B3, alpha: alpha)
}
} }

View File

@ -20,11 +20,13 @@ let SPBaseURL = "https://api-thimratv.thimratv.com"
let SPURLPathPrefix = "/0a2c5b02" let SPURLPathPrefix = "/0a2c5b02"
let SPWebBaseURL = "https://www.thimratv.com" let SPWebBaseURL = "https://www.thimratv.com"
let SPCampaignWebURL = "https://campaign.thimratv.com"
#else #else
let SPBaseURL = "https://api-thimratv.thimratv.com" let SPBaseURL = "https://api-thimratv.thimratv.com"
let SPURLPathPrefix = "/0a2c5b02" let SPURLPathPrefix = "/0a2c5b02"
let SPWebBaseURL = "https://www.thimratv.com" let SPWebBaseURL = "https://www.thimratv.com"
let SPCampaignWebURL = "https://campaign.thimratv.com"
#endif #endif
@ -41,5 +43,8 @@ let SPPersoInforDisclosureWebUrl = SPWebBaseURL + "/persoInfor_disclosure"
/// ///
let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention" let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention"
///
let SPFeedBackHomeWebUrl = SPCampaignWebURL + "/pages/leave/index"

View File

@ -13,7 +13,7 @@ class SPWebView: WKWebView {
weak var delegate: SPWebViewDelegate? weak var delegate: SPWebViewDelegate?
private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [ private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [
WebMessageGetUserInfo, WebMessageAPP,
] ]

View File

@ -10,8 +10,8 @@ import WebKit
typealias SPWebViewMessageName = String typealias SPWebViewMessageName = String
/// ///APP
let WebMessageGetUserInfo: SPWebViewMessageName = "getUserInfo" let WebMessageAPP: SPWebViewMessageName = "js2app"
extension SPWebViewController { extension SPWebViewController {

View File

@ -30,6 +30,8 @@ class SPWebViewController: SPViewController {
// self.edgesForExtendedLayout = .top // self.edgesForExtendedLayout = .top
configNavigationBack() configNavigationBack()
setBackgroundView(isShowGradient: false, bgImage: nil)
_setupUI() _setupUI()
if let url = urlStr { if let url = urlStr {
@ -37,10 +39,6 @@ class SPWebViewController: SPViewController {
} }
} }
override func setBgImageView() {
self.view.backgroundColor = .backgroundColor()
}
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true) self.navigationController?.setNavigationBarHidden(false, animated: true)
@ -79,7 +77,37 @@ extension SPWebViewController: SPWebViewDelegate {
spLog(message: error) spLog(message: error)
} }
func webViewDidFinishLoad(_ webView: SPWebView) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
self?.receiveDataFromNative()
}
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
_webViewUserContentController(didReceive: message) _webViewUserContentController(didReceive: message)
} }
} }
extension SPWebViewController {
func receiveDataFromNative() {
let dic = [
"token" : SPLoginManager.manager.token?.token ?? "",
"time_zone" : String.timeZone(),
"lang" : SPLocalizedManager.shared.currentLocalizedKey,
"type" : "ios",
"theme" : "theme_1",
]
if let json = dic.toJsonString() {
let js = "receiveDataFromNative(\(json))"
self.webView.evaluateJavaScript(js) { _, error in
}
}
}
}

View File

@ -111,7 +111,7 @@ class SPAllShortViewController: SPViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.view.backgroundColor = .clear setBackgroundView(isShowGradient: false, bgImage: nil, backgroundColor: .clear)
requestCategoryList() requestCategoryList()
requestDataArr(page: 1, completer: nil) requestDataArr(page: 1, completer: nil)
@ -122,19 +122,10 @@ class SPAllShortViewController: SPViewController {
override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
let widht: CGFloat = 100
let height = self.tagView.tagHeight
let x = self.tagView.width - widht
let y = self.tagView.height - height
// openGradientLayer.frame = CGRect(x: x, y: y, width: widht, height: height)
openGradientLayer.frame = self.tagView.bounds openGradientLayer.frame = self.tagView.bounds
} }
override func setBgImageView() {
}
override func handleHeaderRefresh(_ completer: (() -> Void)?) { override func handleHeaderRefresh(_ completer: (() -> Void)?) {
requestDataArr(page: 1) { [weak self] in requestDataArr(page: 1) { [weak self] in
self?.collectionView.sp_endHeaderRefreshing() self?.collectionView.sp_endHeaderRefreshing()

View File

@ -0,0 +1,149 @@
//
// SPLoginViewController.swift
// Thimra
//
// Created by on 2025/4/25.
//
import UIKit
class SPLoginViewController: SPViewController {
private lazy var logoImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "login_logo_icon_01"))
return imageView
}()
private lazy var nameImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "login_logo_icon_02"))
return imageView
}()
private lazy var stackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [faceBookButton, appleButton])
stackView.axis = .vertical
stackView.spacing = 18
return stackView
}()
private lazy var faceBookButton: UIButton = {
let button = createButton(title: "Login with Facebook", titleColor: .colorFFFFFF(), icon: UIImage(named: "facebook_icon_01"), background: .color0866FF())
return button
}()
private lazy var appleButton: UIButton = {
let button = createButton(title: "Login with Apple", titleColor: .color333333(), icon: UIImage(named: "apple_icon_01"), background: .colorFFFFFF())
return button
}()
private lazy var agreementLabel: YYLabel = {
let agreementStr = "kLoginAgreementText".localized
let userAgreementStr = "User Agreement".localized
let privacyPolicy = "Privacy Policy".localized
let range1 = agreementStr.ocString().range(of: userAgreementStr)
let range2 = agreementStr.ocString().range(of: privacyPolicy)
let text = NSMutableAttributedString(string: agreementStr)
text.font = .fontMedium(ofSize: 10)
text.color = .colorB0B0B3()
text.setTextHighlight(range1, color: .colorFFFFFF(), backgroundColor: nil) { [weak self] _, _, _, _ in
guard let self = self else { return }
let vc = SPWebViewController()
vc.urlStr = SPUserAgreementWebUrl
self.navigationController?.pushViewController(vc, animated: true)
}
text.setTextHighlight(range2, color: .colorFFFFFF(), backgroundColor: nil) { [weak self] _, _, _, _ in
guard let self = self else { return }
let vc = SPWebViewController()
vc.urlStr = SPPrivacyPolicyWebUrl
self.navigationController?.pushViewController(vc, animated: true)
}
let textContainer = YYTextContainer(size: CGSize(width: kSPScreenWidth - 150, height: 100))
let layout = YYTextLayout(container: textContainer, text: text)
let label = YYLabel()
label.textLayout = layout
label.textAlignment = .center
label.numberOfLines = 0
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = .top
setBackgroundView(isShowGradient: false)
configNavigationBack()
_setupUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
setNavigationNormalStyle(backgroundColor: .clear, isTranslucent: true)
}
private func createButton(title: String, titleColor: UIColor, icon: UIImage?, background: UIColor) -> UIButton {
let button = JXButton(type: .custom)
button.setBackgroundImage(UIImage(color: background), for: .normal)
button.setTitle(title, for: .normal)
button.setTitleColor(titleColor, for: .normal)
button.jx_font = .fontMedium(ofSize: 14)
button.space = 12
button.setImage(icon, for: .normal)
button.layer.cornerRadius = 8
button.layer.masksToBounds = true
button.snp.makeConstraints { make in
make.height.equalTo(48)
}
return button
}
}
extension SPLoginViewController {
private func _setupUI() {
view.addSubview(logoImageView)
view.addSubview(nameImageView)
view.addSubview(stackView)
view.addSubview(agreementLabel)
// view.addSubview(faceBookButton)
logoImageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(kSPStatusbarHeight + kSPMainW(120))
}
nameImageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(logoImageView.snp.bottom).offset(24)
}
stackView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(37)
make.centerX.equalToSuperview()
make.top.equalTo(nameImageView.snp.bottom).offset(40)
}
let size = agreementLabel.textLayout?.textBoundingSize ?? .zero
agreementLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.size.equalTo(size)
// make.right.lessThanOrEqualToSuperview().offset(-50)
make.bottom.equalToSuperview().offset(-(kSPTabbarSafeBottomMargin + 20))
}
}
}

View File

@ -38,7 +38,7 @@ class SPAboutUsViewController: SPViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "About Us".localized self.title = "About Us".localized
setBackgroundView(isShowGradient: false, bgImage: nil)
_setupUI() _setupUI()
} }
@ -48,10 +48,6 @@ class SPAboutUsViewController: SPViewController {
setNavigationNormalStyle() setNavigationNormalStyle()
} }
override func setBgImageView() {
self.view.backgroundColor = .backgroundColor()
}
} }
extension SPAboutUsViewController { extension SPAboutUsViewController {

View File

@ -12,6 +12,7 @@ class SPMineViewController: SPViewController {
private lazy var dataArr: [SPMineItem] = { private lazy var dataArr: [SPMineItem] = {
let arr = [ let arr = [
// SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "Language".localized), // SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "Language".localized),
SPMineItem(type: .feedBack, iconImage: UIImage(named: "feed_back_icon_01"), title: "FeedBack".localized),
SPMineItem(type: .privacyPolicy, iconImage: UIImage(named: "privacy_policy_icon_01"), title: "Privacy Policy".localized), SPMineItem(type: .privacyPolicy, iconImage: UIImage(named: "privacy_policy_icon_01"), title: "Privacy Policy".localized),
SPMineItem(type: .userAgreement, iconImage: UIImage(named: "user_agreement_icon_01"), title: "User Agreement".localized), SPMineItem(type: .userAgreement, iconImage: UIImage(named: "user_agreement_icon_01"), title: "User Agreement".localized),
SPMineItem(type: .aboutUs, iconImage: UIImage(named: "about_us_icon_01"), title: "About Us".localized), SPMineItem(type: .aboutUs, iconImage: UIImage(named: "about_us_icon_01"), title: "About Us".localized),
@ -40,7 +41,7 @@ class SPMineViewController: SPViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setBackgroundView(isShowGradient: false)
requestData() requestData()
_setupUI() _setupUI()
@ -116,6 +117,11 @@ extension SPMineViewController: UITableViewDelegate, UITableViewDataSource {
let vc = SPAboutUsViewController() let vc = SPAboutUsViewController()
self.navigationController?.pushViewController(vc, animated: true) self.navigationController?.pushViewController(vc, animated: true)
case .feedBack:
let vc = SPWebViewController()
vc.urlStr = SPFeedBackHomeWebUrl
self.navigationController?.pushViewController(vc, animated: true)
default: default:
break break
} }

View File

@ -29,6 +29,8 @@ struct SPMineItem {
case informationSharing case informationSharing
/// ///
case persoInforDisclosure case persoInforDisclosure
///
case feedBack
} }

View File

@ -122,8 +122,11 @@ class SPMineHeaderView: UIView {
} }
@objc private func handleLoginButton() { @objc private func handleLoginButton() {
let vc = SPLoginViewController()
let nav = SPNavigationController(rootViewController: vc)
nav.modalPresentationStyle = .fullScreen
self.viewController?.present(nav, animated: true)
} }
} }

View File

@ -46,14 +46,13 @@ class SPCollectListViewController: SPMyListChildViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setBackgroundView(isShowGradient: false, bgImage: nil, backgroundColor: .clear)
requestDataList(page: 1, completer: nil) requestDataList(page: 1, completer: nil)
_setupUI() _setupUI()
} }
override func setBgImageView() { }
override func handleHeaderRefresh(_ completer: (() -> Void)?) { override func handleHeaderRefresh(_ completer: (() -> Void)?) {

View File

@ -48,11 +48,11 @@ class SPPlayHistoryViewController: SPMyListChildViewController {
requestDataList(page: 1, completer: nil) requestDataList(page: 1, completer: nil)
setBackgroundView(isShowGradient: false, bgImage: nil, backgroundColor: .clear)
_setupUI() _setupUI()
} }
override func setBgImageView() { }
override func handleHeaderRefresh(_ completer: (() -> Void)?) { override func handleHeaderRefresh(_ completer: (() -> Void)?) {

View File

@ -0,0 +1,70 @@
//
// SPLoginManager+Apple.swift
// Thimra
//
// Created by on 2025/4/25.
//
import UIKit
import AuthenticationServices
extension SPLoginManager {
///
func appleSignLogin(completer: ((_ model: SPThirdSignModel?) -> Void)?) {
// self.signAppleHandle = completer
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
}
}
//MARK:-------------- ASAuthorizationControllerDelegate --------------
extension SPLoginManager: ASAuthorizationControllerDelegate {
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
let userIdentifier = appleIDCredential.user
let fullName = appleIDCredential.fullName
let email = appleIDCredential.email
let model = SPThirdSignModel()
model.userID = userIdentifier
model.givenName = fullName?.givenName
model.familyName = fullName?.familyName
model.name = fullName?.nickname
model.email = email
spLog(message: userIdentifier)
spLog(message: fullName)
spLog(message: email)
// if let signAppleHandle = signAppleHandle {
// signAppleHandle(model)
// }
}
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
// if let signAppleHandle = signAppleHandle {
// signAppleHandle(nil)
// }
}
}
extension SPLoginManager: ASAuthorizationControllerPresentationContextProviding {
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
return SPAPPTool.getKeyWindow()!
}
}

View File

@ -0,0 +1,15 @@
//
// SPLoginManager+Facebook.swift
// Thimra
//
// Created by on 2025/4/25.
//
import UIKit
//https://developers.facebook.com/docs/facebook-login/ios?checkpoint_src=any
extension SPLoginManager {
}

View File

@ -9,6 +9,12 @@ import UIKit
class SPLoginManager: NSObject { class SPLoginManager: NSObject {
enum LoginType: Int {
case apple
case faceBook
}
static let manager = SPLoginManager() static let manager = SPLoginManager()
private(set) var token: SPTokenModel? private(set) var token: SPTokenModel?
@ -27,6 +33,19 @@ class SPLoginManager: NSObject {
UserDefaults.jx_setObject(token, forKey: kSPLoginTokenDefaultsKey) UserDefaults.jx_setObject(token, forKey: kSPLoginTokenDefaultsKey)
} }
///
func thirdLogin(type: LoginType, presentingViewController: UIViewController) {
switch type {
case .apple:
appleSignLogin { model in
}
default:
break
}
}
} }

View File

@ -0,0 +1,24 @@
//
// SPThirdSignModel.swift
// Thimra
//
// Created by on 2025/4/25.
//
import UIKit
class SPThirdSignModel: NSObject {
var token: String?
var userID: String?
var email: String?
var name: String?
//
var familyName: String?
//
var givenName: String?
var avatar: String?
}

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Vector@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Vector@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Vector@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Vector@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "APP图标 2@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "APP图标 2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Thimra@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Thimra@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -5,12 +5,12 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "bg@2x.png", "filename" : "背景@2x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "bg@3x.png", "filename" : "背景@3x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -20,6 +20,7 @@
"Episodes" = "Episodes"; "Episodes" = "Episodes";
"Save" = "Save"; "Save" = "Save";
"Added" = "Added"; "Added" = "Added";
"FeedBack" = "FeedBack";
"Language" = "Language"; "Language" = "Language";
"Privacy Policy" = "Privacy Policy"; "Privacy Policy" = "Privacy Policy";
"User Agreement" = "User Agreement"; "User Agreement" = "User Agreement";
@ -52,3 +53,7 @@
"Log in" = "Log in"; "Log in" = "Log in";
"kLoginAgreementText" = "By continuing, you agree to the User Agreement and Privacy Policy";