diff --git a/MoviaBox.xcodeproj/project.pbxproj b/MoviaBox.xcodeproj/project.pbxproj index 8246bd4..b597ba7 100644 --- a/MoviaBox.xcodeproj/project.pbxproj +++ b/MoviaBox.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 1BE7892B2DCB0E530001A8F1 /* FacebookCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1BE7892A2DCB0E530001A8F1 /* FacebookCore */; }; + 1BE7892D2DCB0E530001A8F1 /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 1BE7892C2DCB0E530001A8F1 /* FacebookLogin */; }; 1BF22FD12DC2169B0082429A /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 1BF22FD02DC2169B0082429A /* FirebaseAnalytics */; }; 1BF22FD32DC2169B0082429A /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1BF22FD22DC2169B0082429A /* FirebaseCore */; }; 1BF22FD52DC2169B0082429A /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 1BF22FD42DC2169B0082429A /* FirebaseMessaging */; }; @@ -49,6 +51,8 @@ buildActionMask = 2147483647; files = ( 1BF22FD52DC2169B0082429A /* FirebaseMessaging in Frameworks */, + 1BE7892B2DCB0E530001A8F1 /* FacebookCore in Frameworks */, + 1BE7892D2DCB0E530001A8F1 /* FacebookLogin in Frameworks */, 91D08C5AEAE459A3B8EA48C6 /* Pods_MoviaBox.framework in Frameworks */, 1BF22FD32DC2169B0082429A /* FirebaseCore in Frameworks */, 1BF22FD12DC2169B0082429A /* FirebaseAnalytics in Frameworks */, @@ -146,6 +150,7 @@ minimizedProjectReferenceProxies = 1; packageReferences = ( 1BF22FCF2DC2169B0082429A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, + 1BE789292DCB0E530001A8F1 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */, ); preferredProjectObjectVersion = 77; productRefGroup = 1DBC405A2DA4EDFC0093FCB0 /* Products */; @@ -455,6 +460,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 1BE789292DCB0E530001A8F1 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/facebook/facebook-ios-sdk"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 14.1.0; + }; + }; 1BF22FCF2DC2169B0082429A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; @@ -466,6 +479,16 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 1BE7892A2DCB0E530001A8F1 /* FacebookCore */ = { + isa = XCSwiftPackageProductDependency; + package = 1BE789292DCB0E530001A8F1 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */; + productName = FacebookCore; + }; + 1BE7892C2DCB0E530001A8F1 /* FacebookLogin */ = { + isa = XCSwiftPackageProductDependency; + package = 1BE789292DCB0E530001A8F1 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */; + productName = FacebookLogin; + }; 1BF22FD02DC2169B0082429A /* FirebaseAnalytics */ = { isa = XCSwiftPackageProductDependency; package = 1BF22FCF2DC2169B0082429A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; diff --git a/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved b/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved index a525953..179af45 100644 --- a/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329", + "originHash" : "c47d0d305ed42c8e2ce41760feb2ed27468bf8a4c789d72416aad5bed8e64bd2", "pins" : [ { "identity" : "abseil-cpp-binary", @@ -19,6 +19,15 @@ "version" : "11.2.0" } }, + { + "identity" : "facebook-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/facebook/facebook-ios-sdk", + "state" : { + "revision" : "c19607d535864533523d1f437c84035e5fb101cf", + "version" : "14.1.0" + } + }, { "identity" : "firebase-ios-sdk", "kind" : "remoteSourceControl", diff --git a/MoviaBox/AppDelegate/AppDelegate+APNS.swift b/MoviaBox/AppDelegate/AppDelegate+APNS.swift index a4cd17b..e492832 100644 --- a/MoviaBox/AppDelegate/AppDelegate+APNS.swift +++ b/MoviaBox/AppDelegate/AppDelegate+APNS.swift @@ -34,11 +34,25 @@ extension AppDelegate: UNUserNotificationCenterDelegate { } ///APP处于前台是接收通知消息 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { - completionHandler([.badge, .alert]) + completionHandler([.badge, .banner]) } ///点击通知消息进入app func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + if #available(iOS 16.0, *) { + UNUserNotificationCenter.current().setBadgeCount(0) + } else { + UIApplication.shared.applicationIconBadgeNumber = 0 + } + + let userInfo = response.notification.request.content.userInfo + + if let shortPlayId = userInfo["short_play_id"] as? String { + let vc = SPPlayerDetailViewController() + vc.shortPlayId = shortPlayId + SPAPPTool.topViewController()?.navigationController?.pushViewController(vc, animated: true) + } + completionHandler() } diff --git a/MoviaBox/AppDelegate/AppDelegate+Thirdparty.swift b/MoviaBox/AppDelegate/AppDelegate+Thirdparty.swift new file mode 100644 index 0000000..264aedc --- /dev/null +++ b/MoviaBox/AppDelegate/AppDelegate+Thirdparty.swift @@ -0,0 +1,31 @@ +// +// AppDelegate+Thirdparty.swift +// MoviaBox +// +// Created by 佳尔 on 2025/5/7. +// + +import UIKit +import AdjustSdk +#if canImport(FacebookCore) +import FacebookCore +#endif + +extension AppDelegate { + + func registThirdparty(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) { + //Facebook +#if canImport(FacebookCore) + ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions) +#endif + + registAdjust() + } + + + private func registAdjust() { + let config = ADJConfig(appToken: "mtogye6pmha8", environment: ADJEnvironmentProduction) + Adjust.initSdk(config) + } + +} diff --git a/MoviaBox/AppDelegate/AppDelegate.swift b/MoviaBox/AppDelegate/AppDelegate.swift index 1cb99b4..a35dcd6 100644 --- a/MoviaBox/AppDelegate/AppDelegate.swift +++ b/MoviaBox/AppDelegate/AppDelegate.swift @@ -6,9 +6,6 @@ // import UIKit -#if canImport(FacebookCore) -import FacebookCore -#endif @main class AppDelegate: UIResponder, UIApplicationDelegate { @@ -16,10 +13,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - ///Facebook -#if canImport(FacebookCore) - ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions) -#endif + + + self.registThirdparty(application, didFinishLaunchingWithOptions: launchOptions) self.appConfig() ///注册消息通知 @@ -31,7 +27,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil) - + let _ = JXIAPManager.manager // SPLoginManager.manager.requestVisitorLogin(completer: nil) SPLoginManager.manager.updateUserInfo(completer: nil) diff --git a/MoviaBox/Base/Networking/API/SPHomeAPI.swift b/MoviaBox/Base/Networking/API/SPHomeAPI.swift index bf027cc..46f0dfd 100644 --- a/MoviaBox/Base/Networking/API/SPHomeAPI.swift +++ b/MoviaBox/Base/Networking/API/SPHomeAPI.swift @@ -37,8 +37,9 @@ class SPHomeAPI: NSObject { ///首页模块接口 static func requestHomeModuleData(completer: ((_ model: SPHomeModuleModel?) -> Void)?) { - let param = SPNetworkParameters(path: "/homeBannerAndNineSquare") -// param.method = .get + var param = SPNetworkParameters(path: "/homeModuleData") +// let param = SPNetworkParameters(path: "/homeBannerAndNineSquare") + param.method = .get SPNetwork.request(parameters: param) { (response: SPNetworkResponse) in completer?(response.data) diff --git a/MoviaBox/Base/Networking/API/SPVideoAPI.swift b/MoviaBox/Base/Networking/API/SPVideoAPI.swift index 641aa01..7ceb976 100644 --- a/MoviaBox/Base/Networking/API/SPVideoAPI.swift +++ b/MoviaBox/Base/Networking/API/SPVideoAPI.swift @@ -15,9 +15,9 @@ class SPVideoAPI: NSObject { "short_play_id" : shortPlayId ] - if let videoId = videoId { - parameters["video_id"] = videoId - } +// if let videoId = videoId { +// } + parameters["video_id"] = "0" if let activityId = activityId { parameters["activity_id"] = activityId } diff --git a/MoviaBox/Base/Networking/Base/SPURLPath.swift b/MoviaBox/Base/Networking/Base/SPURLPath.swift index 35c5669..6592d1a 100644 --- a/MoviaBox/Base/Networking/Base/SPURLPath.swift +++ b/MoviaBox/Base/Networking/Base/SPURLPath.swift @@ -17,16 +17,16 @@ import UIKit #if DEBUG let SPBaseURL = "https://api-thimratv.thimratv.com" -let SPURLPathPrefix = "/0a2c5b02" +let SPURLPathPrefix = "/93f03506" let SPWebBaseURL = "https://www.thimratv.com" -let SPCampaignWebURL = "https://campaign.thimratv.com" +let SPCampaignWebURL = "https://campaign.moviatv.com" #else let SPBaseURL = "https://api-thimratv.thimratv.com" -let SPURLPathPrefix = "/0a2c5b02" +let SPURLPathPrefix = "/93f03506" let SPWebBaseURL = "https://www.thimratv.com" -let SPCampaignWebURL = "https://campaign.thimratv.com" +let SPCampaignWebURL = "https://campaign.moviatv.com" #endif @@ -42,6 +42,8 @@ let SPInformationSharingWebUrl = SPWebBaseURL + "/information_sharing" let SPPersoInforDisclosureWebUrl = SPWebBaseURL + "/persoInfor_disclosure" ///全国青少年互联网文明公约 let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention" +///会员服务协议 +let SPMemberShipAgreement = SPWebBaseURL + "/member_ship_agreement" ///反馈首页 let SPFeedBackHomeWebUrl = SPCampaignWebURL + "/pages/leave/index" diff --git a/MoviaBox/Class/Explore/View/SPExplorePlayerControlView.swift b/MoviaBox/Class/Explore/View/SPExplorePlayerControlView.swift index e819f05..faaef93 100644 --- a/MoviaBox/Class/Explore/View/SPExplorePlayerControlView.swift +++ b/MoviaBox/Class/Explore/View/SPExplorePlayerControlView.swift @@ -97,6 +97,9 @@ extension SPExplorePlayerControlView { self.viewController?.navigationController?.pushViewController(vc, animated: true) } + override func handleEpisodeButton() { + self.handleAllEpisodeButton() + } } diff --git a/MoviaBox/Class/Home/View/SPHomeHeaderView.swift b/MoviaBox/Class/Home/View/SPHomeHeaderView.swift index 372e94f..5592ba7 100644 --- a/MoviaBox/Class/Home/View/SPHomeHeaderView.swift +++ b/MoviaBox/Class/Home/View/SPHomeHeaderView.swift @@ -64,8 +64,8 @@ class SPHomeHeaderView: UICollectionReusableView { view.itemSize = .init(width: 234, height: Self.bannerHeight()) view.itemAlpha = true view.itemZoomScale = 0.9 - view.itemSpacing = 10 - view.rotationAngle = 10 + view.itemSpacing = 30 + view.rotationAngle = 12 view.delegate = self view.dataSource = self view.hidesPageControl = true diff --git a/MoviaBox/Class/Login/Controller/SPLoginViewController.swift b/MoviaBox/Class/Login/Controller/SPLoginViewController.swift index 2faf494..1b99bac 100644 --- a/MoviaBox/Class/Login/Controller/SPLoginViewController.swift +++ b/MoviaBox/Class/Login/Controller/SPLoginViewController.swift @@ -11,13 +11,15 @@ class SPLoginViewController: SPViewController { private lazy var logoImageView: UIImageView = { let imageView = UIImageView(image: UIImage(named: "login_logo_icon_01")) + imageView.layer.cornerRadius = 10 + imageView.layer.masksToBounds = true return imageView }() - private lazy var nameImageView: UIImageView = { - let imageView = UIImageView(image: UIImage(named: "login_logo_icon_02")) - 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]) @@ -136,7 +138,7 @@ extension SPLoginViewController { private func _setupUI() { view.addSubview(logoImageView) - view.addSubview(nameImageView) +// view.addSubview(nameImageView) view.addSubview(stackView) view.addSubview(agreementLabel) // view.addSubview(faceBookButton) @@ -146,15 +148,15 @@ extension SPLoginViewController { make.top.equalToSuperview().offset(kSPStatusbarHeight + kSPMainW(120)) } - nameImageView.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.top.equalTo(logoImageView.snp.bottom).offset(24) - } +// 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) + make.top.equalTo(logoImageView.snp.bottom).offset(40) } let size = agreementLabel.textLayout?.textBoundingSize ?? .zero diff --git a/MoviaBox/Class/Mine/View/SPMineHeaderView.swift b/MoviaBox/Class/Mine/View/SPMineHeaderView.swift index d581ef7..1013ea0 100644 --- a/MoviaBox/Class/Mine/View/SPMineHeaderView.swift +++ b/MoviaBox/Class/Mine/View/SPMineHeaderView.swift @@ -10,7 +10,7 @@ import UIKit class SPMineHeaderView: UIView { var contentHeight: CGFloat { - var height: CGFloat = kSPStatusbarHeight + 108 + var height: CGFloat = kSPStatusbarHeight + 100 var stackHeight = 0.0 stackHeight += memberView.intrinsicContentSize.height @@ -219,7 +219,7 @@ extension SPMineHeaderView { stackView.snp.makeConstraints { make in make.left.right.equalToSuperview() - make.top.equalToSuperview().offset(kSPStatusbarHeight + 108) + make.top.equalToSuperview().offset(kSPStatusbarHeight + 100) } } diff --git a/MoviaBox/Class/MyList/Controller/SPCollectListViewController.swift b/MoviaBox/Class/MyList/Controller/SPCollectListViewController.swift index efbaca2..4a5c3b4 100644 --- a/MoviaBox/Class/MyList/Controller/SPCollectListViewController.swift +++ b/MoviaBox/Class/MyList/Controller/SPCollectListViewController.swift @@ -149,14 +149,10 @@ extension SPCollectListViewController: UICollectionViewDelegate, UICollectionVie func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { let count = self.dataArr.count if count == 0 { - let parameters = SPEmptyParameters(image: UIImage(named: "empty_image_01")) - let emptyState = SPEmptyState.normail(parameters: parameters) - self.collectionView.emptyState.format = emptyState.format - self.collectionView.emptyState.show(emptyState) + self.collectionView.addNormalEmpty() } else { - self.collectionView.emptyState.hide() + self.collectionView.hiddenEmpty() } - return count } diff --git a/MoviaBox/Class/MyList/Controller/SPPlayHistoryViewController.swift b/MoviaBox/Class/MyList/Controller/SPPlayHistoryViewController.swift index 0334948..19dd608 100644 --- a/MoviaBox/Class/MyList/Controller/SPPlayHistoryViewController.swift +++ b/MoviaBox/Class/MyList/Controller/SPPlayHistoryViewController.swift @@ -143,13 +143,11 @@ extension SPPlayHistoryViewController: UICollectionViewDelegate, UICollectionVie func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { let count = self.dataArr.count + if count == 0 { - let parameters = SPEmptyParameters(image: UIImage(named: "empty_image_01")) - let emptyState = SPEmptyState.normail(parameters: parameters) - self.collectionView.emptyState.format = emptyState.format - self.collectionView.emptyState.show(emptyState) + self.collectionView.addNormalEmpty() } else { - self.collectionView.emptyState.hide() + self.collectionView.hiddenEmpty() } return count diff --git a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift index d86f708..b53aab5 100644 --- a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift +++ b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift @@ -18,7 +18,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController { } - var videoId: String? + var videoId: String? = "0" var shortPlayId: String? var activityId: String? var playHistoryModel: SPShortModel? @@ -56,8 +56,14 @@ class SPPlayerDetailViewController: SPPlayerListViewController { return view }() + deinit { + NotificationCenter.default.removeObserver(self) + } + override func viewDidLoad() { super.viewDidLoad() + NotificationCenter.default.addObserver(self, selector: #selector(buyVipFinishNotification), name: SPIAPManager.buyVipFinishNotification, object: nil) + self.autoNextEpisode = true self.dataSource = self self.delegate = self @@ -67,6 +73,8 @@ class SPPlayerDetailViewController: SPPlayerListViewController { _addAction() _setupUI() + + } @@ -82,7 +90,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController { if videoInfo.is_lock == true { self.pause() //我的金币 - let myCoin = SPLoginManager.manager.userInfo?.coin_left_total ?? 0 + let myCoin = (SPLoginManager.manager.userInfo?.coin_left_total ?? 0) + (SPLoginManager.manager.userInfo?.send_coin_left_total ?? 0) //解锁视频需要的金币 let videoCoin = videoInfo.coins ?? 0 @@ -197,7 +205,18 @@ extension SPPlayerDetailViewController { } + } + + @objc private func buyVipFinishNotification() { + guard SPLoginManager.manager.userInfo?.is_vip == true else { return } + self.detailModel?.episodeList?.forEach({ + $0.is_lock = false + }) + + self.reloadData { [weak self] in + self?.play() + } } } @@ -253,6 +272,24 @@ extension SPPlayerDetailViewController { self.reloadData { [weak self] in guard let self = self else { return } + if let videoInfo = self.detailModel?.video_info { + var row: Int? + self.detailModel?.episodeList?.enumerated().forEach({ + if $1.id == videoInfo.id { + row = $0 + } + }) + if let row = row { + self.scrollToItem(indexPath: IndexPath(row: row, section: 0), animated: false) + } else { + self.play() + } + + } else { + self.play() + } + + /* if let playHistoryModel = self.playHistoryModel { var row: Int? self.detailModel?.episodeList?.enumerated().forEach({ @@ -267,6 +304,7 @@ extension SPPlayerDetailViewController { } else { self.play() } + */ } } diff --git a/MoviaBox/Class/Player/View/SPPlayBuyView.swift b/MoviaBox/Class/Player/View/SPPlayBuyView.swift index 49b9c93..f30f6ed 100644 --- a/MoviaBox/Class/Player/View/SPPlayBuyView.swift +++ b/MoviaBox/Class/Player/View/SPPlayBuyView.swift @@ -40,7 +40,7 @@ class SPPlayBuyView: HWPanModalContentView { let label = UILabel() label.font = .fontMedium(ofSize: 16) label.textColor = .colorFFFFFF() - label.text = "Stroe".localized + label.text = "Store".localized return label }() @@ -122,6 +122,10 @@ extension SPPlayBuyView { guard let self = self else { return } self.rechargeView.userInfo = SPLoginManager.manager.userInfo } + + self.dismiss(animated: true) { + + } } @objc private func handleRestoreButton() { @@ -186,7 +190,7 @@ extension SPPlayBuyView { SPWalletAPI.requestPayTemplate { [weak self] templateModel in guard let self = self else { return } self.rechargeView.dataArr = templateModel?.list_coins - self.memberView.dataArr = templateModel?.list_sub_vip + self.memberView.setDataArr(dataArr: templateModel?.list_sub_vip) self.stackView.removeAllArrangedSubview() diff --git a/MoviaBox/Class/Player/View/SPPlayerControlView.swift b/MoviaBox/Class/Player/View/SPPlayerControlView.swift index 8a5fb5e..89273e4 100644 --- a/MoviaBox/Class/Player/View/SPPlayerControlView.swift +++ b/MoviaBox/Class/Player/View/SPPlayerControlView.swift @@ -94,7 +94,7 @@ class SPPlayerControlView: UIView { ///右边功能区 private(set) lazy var rightFeatureView: UIStackView = { - let view = UIStackView(arrangedSubviews: [collectButton]) + let view = UIStackView(arrangedSubviews: [collectButton, episodeButton]) view.axis = .vertical view.spacing = 25 return view @@ -107,6 +107,12 @@ class SPPlayerControlView: UIView { return button }() + private lazy var episodeButton: UIButton = { + let button = createFeatureButton(title: "Series".localized, image: UIImage(named: "episode_icon_02")) + button.addTarget(self, action: #selector(handleEpisodeButton), for: .touchUpInside) + return button + }() + deinit { viewModel?.removeObserver(self, forKeyPath: "isPlaying") NotificationCenter.default.removeObserver(self) @@ -204,6 +210,8 @@ extension SPPlayerControlView { extension SPPlayerControlView { + @objc func handleEpisodeButton() {} + @objc private func hadlePlayAndOrPaused() { self.viewModel?.handlePauseOrPlay?() diff --git a/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift b/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift index 9687081..10d82fc 100644 --- a/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift +++ b/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift @@ -97,12 +97,6 @@ class SPPlayerDetailControlView: SPPlayerControlView { private var timer: Timer? //MARK: UI属性 - private lazy var episodeButton: UIButton = { - let button = createFeatureButton(title: "Episodes".localized, image: UIImage(named: "episode_icon_02")) - button.addTarget(self, action: #selector(handleEpisodeButton), for: .touchUpInside) - return button - }() - private lazy var progressTimeLabel: UILabel = { let label = UILabel() label.font = .fontRegular(ofSize: 12) @@ -244,7 +238,6 @@ class SPPlayerDetailControlView: SPPlayerControlView { extension SPPlayerDetailControlView { private func _setupUI() { - self.rightFeatureView.addArrangedSubview(episodeButton) toolView.addSubview(progressTimeLabel) addSubview(retreatButton) @@ -276,7 +269,7 @@ extension SPPlayerDetailControlView { } extension SPPlayerDetailControlView { - @objc private func handleEpisodeButton() { + @objc override func handleEpisodeButton() { self.viewModel?.handleEpisode?() } diff --git a/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift b/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift index 7d03844..e6f322c 100644 --- a/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift +++ b/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift @@ -16,8 +16,15 @@ class SPRewardsViewController: SPCampaignWebViewController { NotificationCenter.default.addObserver(self, selector: #selector(loginStateDidChangeNotification), name: SPLoginManager.loginStateDidChangeNotification, object: nil) + self.webView.scrollView.sp_addRefreshHeader { [weak self] in + self?.handleHeaderRefresh(nil) + } } + override func handleHeaderRefresh(_ completer: (() -> Void)?) { + self.reload() + self.webView.scrollView.sp_endHeaderRefreshing() + } diff --git a/MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift b/MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift index 347f40c..deea27a 100644 --- a/MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift +++ b/MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift @@ -75,7 +75,13 @@ extension SPCoinOrderRecordViewController: UITableViewDelegate, UITableViewDataS } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return self.dataArr.count + let count = self.dataArr.count + if count == 0 { + self.tableView.addNormalEmpty() + } else { + self.tableView.hiddenEmpty() + } + return count } } diff --git a/MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift b/MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift index 2f044c5..39dd8a6 100644 --- a/MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift +++ b/MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift @@ -81,7 +81,13 @@ extension SPConsumptionRecordsViewController: UITableViewDelegate, UITableViewDa } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return self.dataArr.count + let count = self.dataArr.count + if count == 0 { + self.tableView.addNormalEmpty() + } else { + self.tableView.hiddenEmpty() + } + return count } } diff --git a/MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift b/MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift index d98411e..60da69e 100644 --- a/MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift +++ b/MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift @@ -83,7 +83,13 @@ extension SPRewardCoinsViewController: UITableViewDelegate, UITableViewDataSourc } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return self.dataArr.count + let count = self.dataArr.count + if count == 0 { + self.tableView.addNormalEmpty() + } else { + self.tableView.hiddenEmpty() + } + return count } } diff --git a/MoviaBox/Class/Wallet/Controller/SPStoreViewController.swift b/MoviaBox/Class/Wallet/Controller/SPStoreViewController.swift index da14f1c..e59cf01 100644 --- a/MoviaBox/Class/Wallet/Controller/SPStoreViewController.swift +++ b/MoviaBox/Class/Wallet/Controller/SPStoreViewController.swift @@ -54,6 +54,47 @@ class SPStoreViewController: SPViewController { return label }() + private lazy var agreementLabel: YYLabel = { + let text1 = "Terms of Service".localized + let text2 = "Privacy Policy".localized + let text3 = "Renewal Agreement".localized + let text = "\(text1) | \(text2)\n\(text3)" + let range1 = text.ocString().range(of: text1) + let range2 = text.ocString().range(of: text2) + let range3 = text.ocString().range(of: text3) + + let string = NSMutableAttributedString(string: text) + string.color = tipTextLabel.textColor + string.font = tipTextLabel.font + + string.setTextHighlight(range1, color: nil, backgroundColor: nil) { [weak self] _, _, _, _ in + guard let self = self else { return } + let vc = SPWebViewController() + vc.urlStr = SPUserAgreementWebUrl + self.navigationController?.pushViewController(vc, animated: true) + } + + string.setTextHighlight(range2, color: nil, backgroundColor: nil) { [weak self] _, _, _, _ in + guard let self = self else { return } + let vc = SPWebViewController() + vc.urlStr = SPPrivacyPolicyWebUrl + self.navigationController?.pushViewController(vc, animated: true) + } + + string.setTextHighlight(range3, color: nil, backgroundColor: nil) { [weak self] _, _, _, _ in + guard let self = self else { return } + let vc = SPWebViewController() + vc.urlStr = SPMemberShipAgreement + self.navigationController?.pushViewController(vc, animated: true) + } + + + let label = YYLabel() + label.numberOfLines = 0 + label.attributedText = string + return label + }() + override func viewDidLoad() { super.viewDidLoad() self.title = "Store".localized @@ -105,6 +146,7 @@ extension SPStoreViewController { scrollView.addSubview(stackView) scrollView.addSubview(tipTitleLabel) scrollView.addSubview(tipTextLabel) + scrollView.addSubview(agreementLabel) scrollView.snp.makeConstraints { make in make.left.right.bottom.equalToSuperview() @@ -126,6 +168,12 @@ extension SPStoreViewController { make.left.equalTo(tipTitleLabel) make.right.lessThanOrEqualTo(stackView).offset(-24) make.top.equalTo(tipTitleLabel.snp.bottom).offset(4) +// make.bottom.equalTo(-(kSPTabbarSafeBottomMargin + 10)) + } + + agreementLabel.snp.makeConstraints { make in + make.top.equalTo(tipTextLabel.snp.bottom).offset(20) + make.left.equalTo(tipTextLabel) make.bottom.equalTo(-(kSPTabbarSafeBottomMargin + 10)) } } @@ -139,7 +187,7 @@ extension SPStoreViewController { SPWalletAPI.requestPayTemplate { [weak self] templateModel in guard let self = self else { return } self.rechargeView.dataArr = templateModel?.list_coins - self.memberView.dataArr = templateModel?.list_sub_vip + self.memberView.setDataArr(dataArr: templateModel?.list_sub_vip) self.stackView.removeAllArrangedSubview() diff --git a/MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift b/MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift index a2960bb..54abeae 100644 --- a/MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift +++ b/MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift @@ -74,7 +74,13 @@ extension SPVIPOrderRecordViewController: UITableViewDelegate, UITableViewDataSo } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return self.dataArr.count + let count = self.dataArr.count + if count == 0 { + self.tableView.addNormalEmpty() + } else { + self.tableView.hiddenEmpty() + } + return count } } diff --git a/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift b/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift index 0531030..90d4e4a 100644 --- a/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift +++ b/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift @@ -26,7 +26,7 @@ class SPCoinRechargeView: UIView { var userInfo: SPUserInfo? { didSet { - coinLabel.text = "\(userInfo?.coin_left_total ?? 0)" + coinLabel.text = "\((userInfo?.coin_left_total ?? 0) + (userInfo?.send_coin_left_total ?? 0))" } } @@ -38,7 +38,7 @@ class SPCoinRechargeView: UIView { let label = UILabel() label.font = .fontRegular(ofSize: 14) label.textColor = .colorFFFFFF(alpha: 0.7) - label.text = "Coins Balance:" + label.text = "Coins Balance:".localized return label }() diff --git a/MoviaBox/Class/Wallet/View/SPMemberRechargeView.swift b/MoviaBox/Class/Wallet/View/SPMemberRechargeView.swift index 6f27aac..29f297d 100644 --- a/MoviaBox/Class/Wallet/View/SPMemberRechargeView.swift +++ b/MoviaBox/Class/Wallet/View/SPMemberRechargeView.swift @@ -19,13 +19,7 @@ class SPMemberRechargeView: UIView { ///会员购买成功 var buyFinishHandle: (() -> Void)? - var dataArr: [SPPayTemplateItem]? { - didSet { - self.invalidateIntrinsicContentSize() - - self.collectionView.reloadData() - } - } + private var dataArr: [SPPayTemplateItem]? var shortPlayId: String? var videoId: String? @@ -67,6 +61,19 @@ class SPMemberRechargeView: UIView { fatalError("init(coder:) has not been implemented") } + ///设置数据 + func setDataArr(dataArr: [SPPayTemplateItem]?) { + self.dataArr = [] + + dataArr?.forEach({ + if $0.vip_type_key == .quarter { + self.dataArr?.append($0) + } + }) + self.collectionView.reloadData() + self.invalidateIntrinsicContentSize() + } + } extension SPMemberRechargeView { diff --git a/MoviaBox/Libs/Empty/SPEmptyState.swift b/MoviaBox/Libs/Empty/SPEmptyState.swift index 858ca5a..56b43f6 100644 --- a/MoviaBox/Libs/Empty/SPEmptyState.swift +++ b/MoviaBox/Libs/Empty/SPEmptyState.swift @@ -33,7 +33,7 @@ extension SPEmptyState: CustomState { var title: String? { switch self { - case .normail(let parameters): + case .normail(_): return nil } @@ -53,8 +53,9 @@ extension SPEmptyState { var format = EmptyStateFormat() format.backgroundColor = .clear format.imageSize = self.image?.size ?? .zero -// format.verticalMargin = -10 -// + format.animation = nil + format.verticalMargin = -50 +// // format.buttonWidth = 107 // format.buttonTopMargin = 10 // format.buttonColor = .system_fill_primary_100 diff --git a/MoviaBox/Libs/Empty/UIScrollView+Empty.swift b/MoviaBox/Libs/Empty/UIScrollView+Empty.swift new file mode 100644 index 0000000..de4e7c3 --- /dev/null +++ b/MoviaBox/Libs/Empty/UIScrollView+Empty.swift @@ -0,0 +1,23 @@ +// +// UIScrollView+Empty.swift +// MoviaBox +// +// Created by 佳尔 on 2025/5/8. +// + +import UIKit + + +extension UIScrollView { + + func addNormalEmpty() { + let parameters = SPEmptyParameters() + let emptyState = SPEmptyState.normail(parameters: parameters) + self.emptyState.format = emptyState.format + self.emptyState.show(emptyState) + } + + func hiddenEmpty() { + self.emptyState.hide() + } +} diff --git a/MoviaBox/Libs/Player/SPPlayer.swift b/MoviaBox/Libs/Player/SPPlayer.swift index cfe7815..664570b 100644 --- a/MoviaBox/Libs/Player/SPPlayer.swift +++ b/MoviaBox/Libs/Player/SPPlayer.swift @@ -132,7 +132,7 @@ class SPPlayer: NSObject { ///准备播放 func prepare() { -// self.player.prepareToPlay() + self.player.prepareToPlay() } func stop() { @@ -254,6 +254,7 @@ extension SPPlayer { self.replay() } else { self.isPlaying = false + self.prepare() self.delegate?.sp_playCompletion?(self) } } diff --git a/MoviaBox/Libs/SPIAPManager/SPIAPManager.swift b/MoviaBox/Libs/SPIAPManager/SPIAPManager.swift index a1f6ea6..a6d9ed6 100644 --- a/MoviaBox/Libs/SPIAPManager/SPIAPManager.swift +++ b/MoviaBox/Libs/SPIAPManager/SPIAPManager.swift @@ -34,7 +34,7 @@ class SPIAPManager: NSObject { ///开始内购 func startRecharge(model: SPPayTemplateItem, shortPlayId: String? = nil, videoId: String? = nil, handler: CompletionHandler? = nil) { - if let waitRestoreModel = self.waitRestoreModel { + if let _ = self.waitRestoreModel { SPToast.show(text: "kToastMessage_02".localized) handler?(false) return @@ -46,6 +46,11 @@ class SPIAPManager: NSObject { } self.completionHandler = handler self.waitRestoreModel = SPWaitRestoreModel() + if model.buy_type == .coins { + self.waitRestoreModel?.buyType = .coins + } else if model.buy_type == .subVip { + self.waitRestoreModel?.buyType = .vip + } let productId = SPIAPManager.IAPPrefix + (model.ios_template_id ?? "") @@ -86,26 +91,35 @@ class SPIAPManager: NSObject { SPHUD.show() } SPWalletAPI.requestVerifyOrder(orderCode: orderCode, payId: payId, productId: productId, purchaseToken: receipt) { model in - if model?.status == "success" { - self.waitRestoreModel = nil - UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) + if isLoding { + SPHUD.dismiss() + } + + guard let model = model else { + completer?(false) + return + } + let buyType = self.waitRestoreModel?.buyType + self.waitRestoreModel = nil + UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) + + if model.status == "success" { + SPLoginManager.manager.userInfo?.is_vip = true + if isLoding { SPToast.show(text: "success".localized) } completer?(true) + if buyType == .vip { + NotificationCenter.default.post(name: SPIAPManager.buyVipFinishNotification, object: nil) + } } else { // SPToast.show(text: "failure".localized) completer?(false) } - - if isLoding { - SPHUD.dismiss() - } } } - - } //MARK: -------------- JXIAPManagerDelegate -------------- @@ -131,11 +145,23 @@ extension SPIAPManager: JXIAPManagerDelegate { self.orderCode = nil self.payId = nil - if model?.status == "success" { - self.waitRestoreModel = nil - UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) + guard let model = model else { + self.completionHandler?(false) + return + } + + let buyType = self.waitRestoreModel?.buyType + self.waitRestoreModel = nil + UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) + + if model.status == "success" { + SPLoginManager.manager.userInfo?.is_vip = true + SPToast.show(text: "success".localized) self.completionHandler?(true) + if buyType == .vip { + NotificationCenter.default.post(name: SPIAPManager.buyVipFinishNotification, object: nil) + } } else { self.completionHandler?(false) } @@ -158,3 +184,9 @@ extension SPIAPManager: JXIAPManagerDelegate { } } + +extension SPIAPManager { + ///成功购买会员 + @objc static let buyVipFinishNotification = NSNotification.Name(rawValue: "SPIAPManager.buyVipFinishNotification") + +} diff --git a/MoviaBox/Libs/SPIAPManager/SPIAPVerifyModel.swift b/MoviaBox/Libs/SPIAPManager/SPIAPVerifyModel.swift index e0b8a08..2ba110c 100644 --- a/MoviaBox/Libs/SPIAPManager/SPIAPVerifyModel.swift +++ b/MoviaBox/Libs/SPIAPManager/SPIAPVerifyModel.swift @@ -13,5 +13,6 @@ class SPIAPVerifyModel: SPModel, SmartCodable { var status: String? var money: String? var is_backhaul: String? + var code: String? } diff --git a/MoviaBox/Libs/SPIAPManager/SPWaitRestoreModel.swift b/MoviaBox/Libs/SPIAPManager/SPWaitRestoreModel.swift index b79039e..dfb6f69 100644 --- a/MoviaBox/Libs/SPIAPManager/SPWaitRestoreModel.swift +++ b/MoviaBox/Libs/SPIAPManager/SPWaitRestoreModel.swift @@ -16,6 +16,7 @@ class SPWaitRestoreModel: SPModel, NSSecureCoding { var payId: String? var productId: String? var receipt: String? + var buyType: SPWalletAPI.BuyType? required init() { } @@ -31,6 +32,7 @@ class SPWaitRestoreModel: SPModel, NSSecureCoding { coder.encode(payId, forKey: "payId") coder.encode(productId, forKey: "productId") coder.encode(receipt, forKey: "receipt") + coder.encode(buyType?.rawValue, forKey: "buyType") } required init?(coder: NSCoder) { @@ -39,6 +41,9 @@ class SPWaitRestoreModel: SPModel, NSSecureCoding { payId = coder.decodeObject(of: NSString.self, forKey: "payId") as? String productId = coder.decodeObject(of: NSString.self, forKey: "productId") as? String receipt = coder.decodeObject(of: NSString.self, forKey: "receipt") as? String + if let type = coder.decodeObject(of: NSString.self, forKey: "buyType") as? String { + buyType = SPWalletAPI.BuyType(rawValue: type) + } } } diff --git a/MoviaBox/MoviaBox.entitlements b/MoviaBox/MoviaBox.entitlements index c2078c8..948cd23 100644 --- a/MoviaBox/MoviaBox.entitlements +++ b/MoviaBox/MoviaBox.entitlements @@ -8,6 +8,11 @@ Default + com.apple.developer.associated-domains + + applinks:moviaboxapp.go.link + applinks:www.moviatv.com + keychain-access-groups diff --git a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Contents.json index 292c6c2..8cfadf7 100644 --- a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Contents.json +++ b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "Episodes@2x.png", + "filename" : "Group 79@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "Episodes@3x.png", + "filename" : "Group 79@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Episodes@2x.png b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Episodes@2x.png deleted file mode 100644 index 86c068c..0000000 Binary files a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Episodes@2x.png and /dev/null differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Episodes@3x.png b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Episodes@3x.png deleted file mode 100644 index c97f7e8..0000000 Binary files a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Episodes@3x.png and /dev/null differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Group 79@2x.png b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Group 79@2x.png new file mode 100644 index 0000000..6850ce9 Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Group 79@2x.png differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Group 79@3x.png b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Group 79@3x.png new file mode 100644 index 0000000..a16f4c0 Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/icon/episode_icon_02.imageset/Group 79@3x.png differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/APP图标 2@2x.png b/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/APP图标 2@2x.png deleted file mode 100644 index 75a3c54..0000000 Binary files a/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/APP图标 2@2x.png and /dev/null differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/APP图标 2@3x.png b/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/APP图标 2@3x.png deleted file mode 100644 index c170c77..0000000 Binary files a/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/APP图标 2@3x.png and /dev/null differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/Contents.json index bd1be6e..f8a079e 100644 --- a/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/Contents.json +++ b/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/Contents.json @@ -5,12 +5,11 @@ "scale" : "1x" }, { - "filename" : "APP图标 2@2x.png", + "filename" : "LOGO(MoviaBox).jpg", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "APP图标 2@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/LOGO(MoviaBox).jpg b/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/LOGO(MoviaBox).jpg new file mode 100644 index 0000000..20c1b8d Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/icon/login_logo_icon_01.imageset/LOGO(MoviaBox).jpg differ diff --git a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/Contents.json index 0caa45e..f7eba1d 100644 --- a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/Contents.json +++ b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "空空如也@2x.png", + "filename" : "image 39@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "空空如也@3x.png", + "filename" : "image 39@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/image 39@2x.png b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/image 39@2x.png new file mode 100644 index 0000000..3e419ca Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/image 39@2x.png differ diff --git a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/image 39@3x.png b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/image 39@3x.png new file mode 100644 index 0000000..2ceb59a Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/image 39@3x.png differ diff --git a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@2x.png b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@2x.png deleted file mode 100644 index 985fa2e..0000000 Binary files a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@2x.png and /dev/null differ diff --git a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@3x.png b/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@3x.png deleted file mode 100644 index f3d5df1..0000000 Binary files a/MoviaBox/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@3x.png and /dev/null differ diff --git a/MoviaBox/Source/Info.plist b/MoviaBox/Source/Info.plist index be2b431..25102d7 100644 --- a/MoviaBox/Source/Info.plist +++ b/MoviaBox/Source/Info.plist @@ -14,6 +14,14 @@ fb1228062532660582 + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + MoviaTV + + FacebookAppID @@ -48,6 +56,11 @@ + UIBackgroundModes + + fetch + remote-notification + UIViewControllerBasedStatusBarAppearance diff --git a/MoviaBox/Source/MoviaBox-Bridging-Header.h b/MoviaBox/Source/MoviaBox-Bridging-Header.h index e4afd0a..a6d1475 100644 --- a/MoviaBox/Source/MoviaBox-Bridging-Header.h +++ b/MoviaBox/Source/MoviaBox-Bridging-Header.h @@ -17,3 +17,4 @@ #import "WMPageController.h" #import #import +#import diff --git a/MoviaBox/Source/en.lproj/Localizable.strings b/MoviaBox/Source/en.lproj/Localizable.strings index 9913001..485ec85 100644 --- a/MoviaBox/Source/en.lproj/Localizable.strings +++ b/MoviaBox/Source/en.lproj/Localizable.strings @@ -19,13 +19,15 @@ "Trending Now" = "Trending Now"; "Editor's Hotlist" = "Editor's Hotlist"; "Shorts for You" = "Shorts for You"; -"Episodes" = "Episodes"; +"Series" = "Series"; "Save" = "Save"; "Added" = "Added"; "FeedBack" = "FeedBack"; "Settings" = "Settings"; "Language" = "Language"; "Privacy Policy" = "Privacy Policy"; +"Terms of Service" = "Terms of Service"; +"Renewal Agreement" = "Renewal Agreement"; "User Agreement" = "User Agreement"; "About Us" = "About Us"; "My list" = "My list"; @@ -67,7 +69,6 @@ "Consumption records" = "Consumption records"; "Purchase records" = "Purchase records"; "Reward Coins" = "Reward Coins"; -"Stroe" = "Stroe"; "Coins Balance:" = "Coins Balance:"; "Membership" = "Membership"; "%@ Bonus" = "%@ Bonus"; @@ -106,6 +107,6 @@ "kLoginAgreementText" = "By continuing, you agree to the User Agreement and Privacy Policy"; "kBuyMemberTipText" = "Auto renew · Cancel anytime"; "kStoreTipTitle" = "Related terms and conditions:"; -"kStoreTipText" = "1. Coins can only be used within this application.
2. Payment: The purchase will be charged to your iTunes account. 
3. Renewal: Your Apple iTunes account will be charged within 24 hours before the expiration and the subscription period will be extended for another subscription cycle upon successful deduction.
4. Cancellation: To cancel the subscription renewal, please turn off the automatic renewal function in the iTunes/Apple ID settings at least 24 hours before the current subscription period expires. If canceled within the last 24 hours before expiration, a subscription fee will still be charged. 
5. Payment successful but recharge not taking effect for an extended period? Click here to refresh or send an email to: cs.jiaer.developer@icloud.com. 
6. Manage your subscriptions: You can view, change, or cancel your subscriptions. 

Terms of Service | Privacy Policy 
Renewal Agreement"; +"kStoreTipText" = "1. Coins can only be used within this application.
2. Payment: The purchase will be charged to your iTunes account. 
3. Renewal: Your Apple iTunes account will be charged within 24 hours before the expiration and the subscription period will be extended for another subscription cycle upon successful deduction.
4. Cancellation: To cancel the subscription renewal, please turn off the automatic renewal function in the iTunes/Apple ID settings at least 24 hours before the current subscription period expires. If canceled within the last 24 hours before expiration, a subscription fee will still be charged. 
5. Payment successful but recharge not taking effect for an extended period? Click here to refresh or send an email to: cs.jiaer.developer@icloud.com. 
6. Manage your subscriptions: You can view, change, or cancel your subscriptions. "; "kDeleteAccountCheckText" = "I accept the deletion risk and agree to delete my account"; diff --git a/MoviaBox/Thirdparty/JXIAPManager/JXIAPManager.swift b/MoviaBox/Thirdparty/JXIAPManager/JXIAPManager.swift index 89d648e..1ceb6ae 100644 --- a/MoviaBox/Thirdparty/JXIAPManager/JXIAPManager.swift +++ b/MoviaBox/Thirdparty/JXIAPManager/JXIAPManager.swift @@ -46,7 +46,7 @@ class JXIAPManager: NSObject { private var payment: SKPayment? private var product: SKProduct? - private var productId: String = "" + private var productId: String? private var orderId: String? private var applicationUsername: String? { get { @@ -112,7 +112,10 @@ extension JXIAPManager: SKProductsRequestDelegate { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { guard let product = response.products.first else { DispatchQueue.main.async { - self.delegate?.jx_iapPayFailed?(productId: self.productId, code: .noProduct) + if let productId = self.productId { + self.productId = nil + self.delegate?.jx_iapPayFailed?(productId: productId, code: .noProduct) + } } return } @@ -128,7 +131,7 @@ extension JXIAPManager: SKPaymentTransactionObserver { func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { - + spLog(message: "transactionState = \(transaction.transactionState)") switch transaction.transactionState { case .purchased: DispatchQueue.main.async { @@ -169,14 +172,21 @@ extension JXIAPManager: SKPaymentTransactionObserver { extension JXIAPManager { private func completeTransaction(transaction: SKPaymentTransaction) { //自动续费 - if let _ = transaction.original, transaction.payment.applicationUsername == nil { - return - } +// if let _ = transaction.original, transaction.payment.applicationUsername == nil { +// return +// } //重新开通自动续费 - if let _ = transaction.original, transaction.payment.applicationUsername != nil { - self.delegate?.jx_iapPayFailed?(productId: productId, code: .unknown) - return - } +// if let _ = transaction.original, transaction.payment.applicationUsername != nil { +// self.delegate?.jx_iapPayFailed?(productId: productId, code: .unknown) +// return +// } + + spLog(message: "transactionDate = \(String(describing: transaction.transactionDate))") + spLog(message: "nowDate = \(Date())") + spLog(message: "productIdentifier = \(transaction.payment.productIdentifier)") + + guard let productId = self.productId, productId == transaction.payment.productIdentifier else { return } + self.productId = nil guard let receiptURL = Bundle.main.appStoreReceiptURL else { return } let receiptData = NSData(contentsOf: receiptURL) @@ -184,15 +194,20 @@ extension JXIAPManager { guard let transactionIdentifier = transaction.transactionIdentifier else { return } self.delegate?.jx_iapPaySuccess?(productId: productId, receipt: encodeStr, transactionIdentifier: transactionIdentifier) + } private func failedTransaction(transaction: SKPaymentTransaction) { let error = transaction.error as? SKError + guard let productId = self.productId else { return } + self.productId = nil + switch error?.code { case SKError.paymentCancelled: self.delegate?.jx_iapPayFailed?(productId: productId, code: .cancelled) default: self.delegate?.jx_iapPayFailed?(productId: productId, code: .unknown) } + } } diff --git a/Podfile b/Podfile index 6dbd20d..6ef15fa 100644 --- a/Podfile +++ b/Podfile @@ -31,7 +31,7 @@ target 'MoviaBox' do pod 'WMZPageController' #分页控制器 pod 'SVProgressHUD' #HUD pod 'TZImagePickerController' #相册 -# pod 'FBSDKCoreKit' # Facebook 基础 -# pod 'FBSDKLoginKit' # Facebook 登录 + pod 'Adjust' # Adjust + end diff --git a/Podfile.lock b/Podfile.lock index 417712e..e67bdc4 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,4 +1,9 @@ PODS: + - Adjust (5.3.0): + - Adjust/Adjust (= 5.3.0) + - Adjust/Adjust (5.3.0): + - AdjustSignature (= 3.35.2) + - AdjustSignature (3.35.2) - Alamofire (5.10.2) - CocoaAsyncSocket (7.6.5) - EmptyStateKit (1.1.0) @@ -32,6 +37,7 @@ PODS: - ZFPlayer/Core (4.1.4) DEPENDENCIES: + - Adjust - EmptyStateKit - HWPanModal - Kingfisher @@ -50,6 +56,8 @@ DEPENDENCIES: SPEC REPOS: https://github.com/CocoaPods/Specs.git: + - Adjust + - AdjustSignature - Kingfisher - ZFPlayer trunk: @@ -70,6 +78,8 @@ SPEC REPOS: - YYKit SPEC CHECKSUMS: + Adjust: 3389abb14f761aa0d1966d52814864df9606535e + AdjustSignature: 23b9e5d4adcadffc303bb6b410fde617dd88504f Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 EmptyStateKit: dc41e9ce5c6089f67a49d063bce73ade9f2ba73f @@ -88,6 +98,6 @@ SPEC CHECKSUMS: YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7 ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13 -PODFILE CHECKSUM: 38415be06361089ed99017f8e3cdad9bd57ec94a +PODFILE CHECKSUM: 2a79f81260b8df4d6be58f4acb217732b1cd49ab COCOAPODS: 1.16.2