diff --git a/Podfile b/Podfile index 174a576..0d59aa9 100644 --- a/Podfile +++ b/Podfile @@ -1,6 +1,6 @@ # Uncomment the next line to define a global platform for your project #source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '15.6' +platform :ios, '15.0' post_install do |installer| installer.pods_project.targets.each do |target| diff --git a/Veloria.xcodeproj/project.pbxproj b/Veloria.xcodeproj/project.pbxproj index c298340..5bb38e7 100644 --- a/Veloria.xcodeproj/project.pbxproj +++ b/Veloria.xcodeproj/project.pbxproj @@ -1798,7 +1798,7 @@ CODE_SIGN_ENTITLEMENTS = Veloria/Veloria.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 394VH538M8; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Veloria/Source/Info.plist; @@ -1810,7 +1810,7 @@ INFOPLIST_KEY_UIMainStoryboardFile = ""; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1839,7 +1839,7 @@ CODE_SIGN_ENTITLEMENTS = Veloria/Veloria.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 394VH538M8; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Veloria/Source/Info.plist; @@ -1851,7 +1851,7 @@ INFOPLIST_KEY_UIMainStoryboardFile = ""; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/Veloria/Base/Controller/VPTabBarController.swift b/Veloria/Base/Controller/VPTabBarController.swift index 743e7ea..f94c8f2 100644 --- a/Veloria/Base/Controller/VPTabBarController.swift +++ b/Veloria/Base/Controller/VPTabBarController.swift @@ -55,7 +55,9 @@ class VPTabBarController: UITabBarController { vp_setup() self.tabBar.isTranslucent = true - checkUpdates() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + self?.checkUpdates() + } } @@ -197,7 +199,7 @@ extension VPTabBarController { let alert = VPVersionUpdateAlertView(model: model).show() alert.clickHighlightButton = { [weak self] in - guard let self = self else { return } + guard let _ = self else { return } guard let url = URL(string: "https://apps.apple.com/app/id6746436168") else { return } if UIApplication.shared.canOpenURL(url) { diff --git a/Veloria/Base/Networking/API/VPWalletAPI.swift b/Veloria/Base/Networking/API/VPWalletAPI.swift index 7a9a15e..25a58e1 100644 --- a/Veloria/Base/Networking/API/VPWalletAPI.swift +++ b/Veloria/Base/Networking/API/VPWalletAPI.swift @@ -15,9 +15,10 @@ class VPWalletAPI { } ///获取支付模版 - static func requestPayTemplate(completer: ((_ model: VPPayTemplateModel?) -> Void)?) { + static func requestPayTemplate(isLoding: Bool = false, completer: ((_ model: VPPayTemplateModel?) -> Void)?) { var param = VPNetworkParameters(path: "/paySettingsV3") param.method = .get + param.isLoding = isLoding VPNetwork.request(parameters: param) { (response: VPNetworkResponse) in completer?(response.data) diff --git a/Veloria/Base/WebView/VPWebViewController.swift b/Veloria/Base/WebView/VPWebViewController.swift index 684f543..bce59e5 100644 --- a/Veloria/Base/WebView/VPWebViewController.swift +++ b/Veloria/Base/WebView/VPWebViewController.swift @@ -43,10 +43,12 @@ class VPWebViewController: VPViewController { _setupUI() + showEmptyView() - if let url = urlStr { + if let url = urlStr, VPNetworkReachabilityManager.manager.isReachable == true { self.load(urlString: url) } + } override func viewWillAppear(_ animated: Bool) { @@ -83,6 +85,20 @@ extension VPWebViewController { } } + private func showEmptyView() { + if VPNetworkReachabilityManager.manager.isReachable != true { + if emptyView.superview == nil { + view.addSubview(emptyView) + emptyView.snp.makeConstraints { make in + make.left.equalToSuperview() + make.centerX.equalToSuperview() + make.centerY.equalToSuperview().offset(-100) + } + self.webView.isHidden = true + } + } + } + } //MARK: -------------- VPWebViewDelegate -------------- @@ -114,17 +130,7 @@ extension VPWebViewController: VPWebViewDelegate { VPHUD.dismiss() vpLog(message: error) - if VPNetworkReachabilityManager.manager.isReachable != true { - if emptyView.superview == nil { - view.addSubview(emptyView) - emptyView.snp.makeConstraints { make in - make.left.equalToSuperview() - make.centerX.equalToSuperview() - make.centerY.equalToSuperview().offset(-100) - } - self.webView.isHidden = true - } - } + showEmptyView() } func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { diff --git a/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift b/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift index 0e82378..d6ed09d 100644 --- a/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift +++ b/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift @@ -223,16 +223,18 @@ extension VPDetailPlayerViewController { ///打开充值页面 private func onRecharge() { - guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return } +// guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return } - let view = VPPlayerRechargeView() - view.shortPlayId = videoInfo.short_play_id - view.videoId = videoInfo.short_play_video_id - view.buyFinishBlock = { [weak self] in - guard let self = self else { return } - self.requestDetailData(indexPath: self.viewModel.currentIndexPath) - } - view.present(in: nil) + self.viewModel.showRechargeView() + +// let view = VPPlayerRechargeView() +// view.shortPlayId = videoInfo.short_play_id +// view.videoId = videoInfo.short_play_video_id +// view.buyFinishBlock = { [weak self] in +// guard let self = self else { return } +// self.requestDetailData(indexPath: self.viewModel.currentIndexPath) +// } +// view.present(in: nil) } ///成功开通会员 diff --git a/Veloria/Class/Player/Controller/VPVideoPlayerViewController.swift b/Veloria/Class/Player/Controller/VPVideoPlayerViewController.swift index 14315ff..86cf7dc 100644 --- a/Veloria/Class/Player/Controller/VPVideoPlayerViewController.swift +++ b/Veloria/Class/Player/Controller/VPVideoPlayerViewController.swift @@ -383,7 +383,7 @@ extension VPVideoPlayerViewController { } } -//MARK: -------------- APP生命周期 -------------- +//MARK: -------------- 系统回调 -------------- extension VPVideoPlayerViewController { @objc func didBecomeActiveNotification() { diff --git a/Veloria/Class/Player/View/VPDetailPlayerControlView.swift b/Veloria/Class/Player/View/VPDetailPlayerControlView.swift index 23fee99..a91d93a 100644 --- a/Veloria/Class/Player/View/VPDetailPlayerControlView.swift +++ b/Veloria/Class/Player/View/VPDetailPlayerControlView.swift @@ -127,7 +127,8 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView { button.layer.masksToBounds = true button.configurationUpdateHandler = { [weak self] button in guard let self = self else { return } - button.configuration?.attributedTitle = AttributedString.createAttributedString(string: self.viewModel?.revolution.toString ?? "", color: .colorFFFFFF(), font: .fontRegular(ofSize: 13)) + let revolution = VPVideoRevolutionManager.manager.revolution + button.configuration?.attributedTitle = AttributedString.createAttributedString(string: revolution.toString ?? "", color: .colorFFFFFF(), font: .fontRegular(ofSize: 13)) } button.addTarget(self, action: #selector(handleRevolutionButton), for: .touchUpInside) return button @@ -217,7 +218,7 @@ extension VPDetailPlayerControlView { @objc private func handleRevolutionButton() { addSubview(revolutionSelectedView) - revolutionSelectedView.currentRevolution = self.viewModel?.revolution + revolutionSelectedView.currentRevolution = VPVideoRevolutionManager.manager.revolution revolutionSelectedView.snp.makeConstraints { make in make.edges.equalToSuperview() diff --git a/Veloria/Class/Player/View/VPPlayerRechargeView.swift b/Veloria/Class/Player/View/VPPlayerRechargeView.swift index 05b82be..1149e68 100644 --- a/Veloria/Class/Player/View/VPPlayerRechargeView.swift +++ b/Veloria/Class/Player/View/VPPlayerRechargeView.swift @@ -22,6 +22,43 @@ class VPPlayerRechargeView: HWPanModalContentView { } } + var model: VPPayTemplateModel? { + didSet { + stackView.removeAllArrangedSubview() + + if let model = self.model { + + if let list = model.list_sub_vip, list.count > 0 { + self.stackView.addArrangedSubview(self.vipView) + self.vipView.dataArr = list + } + + if let list = model.list_coins, list.count > 0 { + self.stackView.addArrangedSubview(self.coinsView) + self.coinsView.dataArr = list + } + + if self.stackView.arrangedSubviews.count == 1, + let view = self.stackView.arrangedSubviews.first, + view == self.coinsView { + scrollView.snp.updateConstraints { make in + make.top.equalToSuperview().offset(56) + } + } else { + scrollView.snp.updateConstraints { make in + make.top.equalToSuperview().offset(41) + } + } + + + self.stackView.addArrangedSubview(tipView) + } + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in + self?.panModalSetNeedsLayoutUpdate() + } + } + } + var buyFinishBlock: (() -> Void)? var vipBuyFinishBlock: (() -> Void)? @@ -144,7 +181,7 @@ class VPPlayerRechargeView: HWPanModalContentView { updateCoin() - requestRechargeData() +// requestRechargeData() } required init?(coder: NSCoder) { @@ -275,38 +312,10 @@ extension VPPlayerRechargeView { VPWalletAPI.requestPayTemplate { [weak self] model in guard let self = self else { return } - stackView.removeAllArrangedSubview() + guard let model = model else { return } + self.model = model + - if let model = model { - - if let list = model.list_sub_vip, list.count > 0 { - self.stackView.addArrangedSubview(self.vipView) - self.vipView.dataArr = list - } - - if let list = model.list_coins, list.count > 0 { - self.stackView.addArrangedSubview(self.coinsView) - self.coinsView.dataArr = list - } - - if self.stackView.arrangedSubviews.count == 1, - let view = self.stackView.arrangedSubviews.first, - view == self.coinsView { - scrollView.snp.updateConstraints { make in - make.top.equalToSuperview().offset(56) - } - } else { - scrollView.snp.updateConstraints { make in - make.top.equalToSuperview().offset(41) - } - } - - - self.stackView.addArrangedSubview(tipView) - } - DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in - self?.panModalSetNeedsLayoutUpdate() - } } } diff --git a/Veloria/Class/Player/View/VPVideoPlayerControlView.swift b/Veloria/Class/Player/View/VPVideoPlayerControlView.swift index 2421ef6..b3bc758 100644 --- a/Veloria/Class/Player/View/VPVideoPlayerControlView.swift +++ b/Veloria/Class/Player/View/VPVideoPlayerControlView.swift @@ -162,6 +162,7 @@ class VPVideoPlayerControlView: UIView { playIconImageView.image = UIImage(named: "play_icon_01") hiddenPlayButtonTimer?.invalidate() hiddenPlayButtonTimer = nil + playButton.isHidden = false } } else { playButton.isHidden = true diff --git a/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift b/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift index 8fc57f7..8576ecd 100644 --- a/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift +++ b/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift @@ -30,9 +30,6 @@ class VPVideoPlayViewModel: NSObject { } } - ///当前分辨率 - lazy var revolution: VPShortModel.VideoRevolution = VPVideoRevolutionManager.manager.revolution - ///设置进度 func seekToTime(toTime: Int) { self.currentPlayer?.seekToTime(toTime: toTime) @@ -56,39 +53,58 @@ class VPVideoPlayViewModel: NSObject { extension VPVideoPlayViewModel { ///选择了新的分辨率 func selectedRevolution(revolution: VPShortModel.VideoRevolution) { - guard self.revolution != revolution else { return } + guard VPVideoRevolutionManager.manager.revolution != revolution else { return } let userInfo = VPLoginManager.manager.userInfo if revolution.needLogin, userInfo?.is_tourist != false, userInfo?.is_vip != true { VPLoginManager.manager.openLogin { [weak self] in - guard let self = self else { return } + guard let _ = self else { return } VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) - self.revolution = VPVideoRevolutionManager.manager.revolution } } else if revolution.needVip, userInfo?.is_vip != true { - guard let videoInfo = self.currentPlayer?.videoInfo else { return } + let alert = VPAlertView(title: "veloria_vip_activate_title".localized, subtitle: "veloria_vip_activate_content".localized, icon: UIImage(named: "alert_icon_06"), normalButtonText: "veloria_later".localized, highlightButtonText: "veloria_go".localized).show() + alert.clickHighlightButton = { [weak self] in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { + self?.showRechargeView(revolution: revolution) + } + } + + } else { + VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) + } + + } + + ///展示充值页面 + func showRechargeView(revolution: VPShortModel.VideoRevolution? = nil) { + guard let videoInfo = self.currentPlayer?.videoInfo else { return } + + VPWalletAPI.requestPayTemplate(isLoding: true) { [weak self] model in + guard let self = self else { return } + guard let model = model else { return } let view = VPPlayerRechargeView() + view.model = model view.shortPlayId = videoInfo.short_play_id view.videoId = videoInfo.short_play_video_id view.buyFinishBlock = { [weak self] in guard let self = self else { return } self.updateDetailDataBlock?(self.currentIndexPath) } - view.vipBuyFinishBlock = { [weak self] in - guard let self = self else { return } - VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) - self.revolution = VPVideoRevolutionManager.manager.revolution + if let revolution = revolution { + view.vipBuyFinishBlock = { [weak self] in + guard let _ = self else { return } + VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) + } } - view.present(in: nil) - } else { - VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) - self.revolution = VPVideoRevolutionManager.manager.revolution + view.present(in: VPAppTool.keyWindow) } + + } } diff --git a/Veloria/Libs/Player/VPPlayer.swift b/Veloria/Libs/Player/VPPlayer.swift index 24f5cc4..40b9048 100644 --- a/Veloria/Libs/Player/VPPlayer.swift +++ b/Veloria/Libs/Player/VPPlayer.swift @@ -58,6 +58,8 @@ class VPPlayer: NSObject { weak var delegate: VPPlayerDelegate? private(set) lazy var isPlaying = false + ///系统原因导致的暂停(来电话) + private(set) lazy var systemPause = false private(set) lazy var playState: PlayState = .unknown private(set) lazy var loadState: LoadState = .unknown @@ -168,6 +170,7 @@ class VPPlayer: NSObject { } func start() { + self.systemPause = false self.isPlaying = true // if self.interruptionType != .began { // } @@ -224,7 +227,7 @@ extension VPPlayer { guard let self = self else { return } if playState == .playStatePlaying && !isPlaying { self.pause() - } else if playState == .playStatePaused, isPlaying { + } else if playState == .playStatePaused, isPlaying, !self.systemPause { self.start() } switch playState { @@ -255,7 +258,7 @@ extension VPPlayer { guard let self = self else { return } if loadState == .playable && !isPlaying { self.pause() - } else if loadState == .playable, isPlaying, self.player.playState != .playStatePlaying { + } else if loadState == .playable, isPlaying, self.player.playState != .playStatePlaying, !self.systemPause { self.start() } @@ -281,7 +284,7 @@ extension VPPlayer { } //错误信息 - player.playerPlayFailed = { [weak self] (asset, error) in + player.playerPlayFailed = { (asset, error) in vpLog(message: "错误信息====\(error)") } @@ -319,15 +322,16 @@ extension VPPlayer { guard let interruptionType = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt else { return } self.interruptionType = AVAudioSession.InterruptionType(rawValue: interruptionType) - if self.interruptionType == .began { + if self.interruptionType == .began, self.isPlaying { + self.systemPause = true self.player.pause() - } else { + } else if self.interruptionType == .ended { + self.systemPause = false if self.isPlaying { self.player.play() } } vpLog(message: "======音频发生变化\(interruptionType)") - } @objc private func routeChangeNotification(sender: Notification) { diff --git a/Veloria/Libs/VPIAPManager/VPIAPManager.swift b/Veloria/Libs/VPIAPManager/VPIAPManager.swift index 7d97c43..734aded 100644 --- a/Veloria/Libs/VPIAPManager/VPIAPManager.swift +++ b/Veloria/Libs/VPIAPManager/VPIAPManager.swift @@ -60,6 +60,7 @@ class VPIAPManager { VPHUD.dismiss() self.waitRestoreModel = nil self.completionHandler?(false) + VPToast.show(text: "veloria_network".localized) return } self.orderCode = orderModel.order_code diff --git a/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/Contents.json b/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/Contents.json new file mode 100644 index 0000000..d7583b3 --- /dev/null +++ b/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "通知图标-切图图层@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "通知图标-切图图层@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/通知图标-切图图层@2x.png b/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/通知图标-切图图层@2x.png new file mode 100644 index 0000000..3b2da83 Binary files /dev/null and b/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/通知图标-切图图层@2x.png differ diff --git a/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/通知图标-切图图层@3x.png b/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/通知图标-切图图层@3x.png new file mode 100644 index 0000000..2c3db73 Binary files /dev/null and b/Veloria/Source/Assets.xcassets/icon/alert_icon_06.imageset/通知图标-切图图层@3x.png differ diff --git a/Veloria/Source/en.lproj/Localizable.strings b/Veloria/Source/en.lproj/Localizable.strings index 8c7a09e..d21e6bf 100644 --- a/Veloria/Source/en.lproj/Localizable.strings +++ b/Veloria/Source/en.lproj/Localizable.strings @@ -97,6 +97,10 @@ "veloria_coin_buy_title" = "Top Up | Indefinitely use"; "veloria_update_title" = "Discover a new version"; "veloria_update_now" = "Update Now"; +"veloria_vip_activate_title" = "Unlock HD VIP Access!"; +"veloria_vip_activate_content" = "Activate vip and enjoy HD video privileges."; +"veloria_later" = "Later"; +"veloria_go" = "Go"; "veloria_bonus_count_text" = "+## Bonus";