播放完成统计,播放时长上报,推动提示
This commit is contained in:
parent
94e047a0e9
commit
b78bd95996
@ -19,12 +19,35 @@ extension AppDelegate {
|
||||
center.delegate = self
|
||||
|
||||
center.requestAuthorization(options: [.badge, .sound, .alert]) { grant, error in
|
||||
if grant {
|
||||
// SPRewardsAPI.requestUploadOpenNotify(completer: nil)
|
||||
if !grant {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
if let date = UserDefaults.standard.object(forKey: kSPApnsAlertDefaultsKey) as? Date {
|
||||
#if DEBUG
|
||||
self.showApnsAlert()
|
||||
#else
|
||||
if date.sp_isToday {
|
||||
self.showApnsAlert()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
UserDefaults.standard.set(Date(), forKey: kSPApnsAlertDefaultsKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
UIApplication.shared.registerForRemoteNotifications()
|
||||
}
|
||||
|
||||
private func showApnsAlert() {
|
||||
let alert = UIAlertController(title: nil, message: "kAlertMessage_03".localized, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "Affirm".localized, style: .default, handler: { _ in
|
||||
SPAPPTool.openApnsSetting()
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localized, style: .cancel))
|
||||
|
||||
|
||||
SPAPPTool.topViewController()?.present(alert, animated: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension AppDelegate: UNUserNotificationCenterDelegate {
|
||||
|
@ -40,7 +40,12 @@ extension SceneDelegate {
|
||||
static var hasOpenMessage = false
|
||||
|
||||
func handleOpenAppMessage(webpageURL: URL?) {
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self._handleOpenAppMessage(webpageURL: webpageURL)
|
||||
}
|
||||
}
|
||||
|
||||
private func _handleOpenAppMessage(webpageURL: URL?) {
|
||||
//统计用URL
|
||||
var statUrlStr: String?
|
||||
var data: [String : Any]?
|
||||
@ -85,6 +90,7 @@ extension SceneDelegate {
|
||||
let vc = SPPlayerDetailViewController()
|
||||
vc.shortPlayId = shortPlayId
|
||||
SPAPPTool.topViewController()?.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,20 +18,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
self.registThirdparty(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
|
||||
self.appConfig()
|
||||
///注册消息通知
|
||||
registerAPNS()
|
||||
|
||||
|
||||
///开启网络监控
|
||||
SPNetworkReachabilityManager.manager.startMonitoring()
|
||||
|
||||
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)
|
||||
|
||||
///注册消息通知
|
||||
registerAPNS()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
window?.rootViewController = tabBarController
|
||||
window?.makeKeyAndVisible()
|
||||
|
||||
if let webpageURL = session.stateRestorationActivity?.webpageURL {
|
||||
handleOpenAppMessage(webpageURL: webpageURL)
|
||||
}
|
||||
// if let webpageURL = session.stateRestorationActivity?.webpageURL {
|
||||
// handleOpenAppMessage(webpageURL: webpageURL)
|
||||
// }
|
||||
|
||||
//在线状态统计
|
||||
timer = Timer.scheduledTimer(timeInterval: 60 * 10, target: self, selector: #selector(handleOnLine), userInfo: nil, repeats: true)
|
||||
@ -40,13 +40,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||
// Called when the scene has moved from an inactive state to an active state.
|
||||
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
||||
SPStatAPI.requestEnterApp()
|
||||
handleOpenAppMessage(webpageURL: nil)
|
||||
}
|
||||
|
||||
func sceneWillResignActive(_ scene: UIScene) {
|
||||
// Called when the scene will move from an active state to an inactive state.
|
||||
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
||||
SPStatAPI.requestEnterApp()
|
||||
}
|
||||
|
||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||
|
@ -17,3 +17,6 @@ let kSPHomeSearchHistoryDefaultsKey = "kSPHomeSearchHistoryDefaultsKey"
|
||||
|
||||
///待恢复数据
|
||||
let kSPWaitRestoreIAPDefaultsKey = "kSPWaitRestoreIAPDefaultsKey"
|
||||
|
||||
///推送提示
|
||||
let kSPApnsAlertDefaultsKey = "kSPApnsAlertDefaultsKey"
|
||||
|
@ -19,6 +19,21 @@ extension Date {
|
||||
let dateComponents = Calendar.current.dateComponents([.day], from: self, to: date)
|
||||
return dateComponents.day ?? 0
|
||||
}
|
||||
|
||||
///是否是今天
|
||||
var sp_isToday: Bool {
|
||||
get {
|
||||
return Calendar.current.isDateInToday(self)
|
||||
}
|
||||
}
|
||||
///是否是昨天
|
||||
var sp_isYesterday: Bool {
|
||||
return Calendar.current.isDateInYesterday(self)
|
||||
}
|
||||
///是否是明天
|
||||
var sp_isTomorrow: Bool {
|
||||
return Calendar.current.isDateInTomorrow(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ class SPVideoAPI: NSObject {
|
||||
}
|
||||
|
||||
///创建播放记录
|
||||
static func requestRequestVideoPlayHistory(videoId: String, shortPlayId: String) {
|
||||
static func requestCreateVideoPlayHistory(videoId: String, shortPlayId: String) {
|
||||
var param = SPNetworkParameters(path: "/createHistory")
|
||||
param.isLoding = false
|
||||
param.isToast = false
|
||||
@ -46,6 +46,39 @@ class SPVideoAPI: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
///视频观看结束
|
||||
static func requestViewingFinish(shortPlayId: String, videoId: String, activityId: String) {
|
||||
var param = SPNetworkParameters(path: "/activeAfterWatchingVideo")
|
||||
param.isLoding = false
|
||||
param.isToast = false
|
||||
param.parameters = [
|
||||
"short_play_video_id" : videoId,
|
||||
"short_play_id" : shortPlayId,
|
||||
"activity_id" : activityId
|
||||
]
|
||||
|
||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
///上报播放时长
|
||||
static func requestUploadPlayTime(shortPlayId: String, videoId: String, seconds: Int) {
|
||||
|
||||
var param = SPNetworkParameters(path: "/uploadHistorySeconds")
|
||||
param.isLoding = false
|
||||
param.isToast = false
|
||||
param.parameters = [
|
||||
"video_id" : videoId,
|
||||
"short_play_id" : shortPlayId,
|
||||
"play_seconds" : seconds
|
||||
]
|
||||
|
||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
///收藏短剧
|
||||
static func requestCollectShort(isCollect: Bool, shortPlayId: String, videoId: String?, success: (() -> Void)?, failure: (() -> Void)? = nil) {
|
||||
let path: String
|
||||
|
@ -89,15 +89,7 @@ extension SPWebViewController {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if settings.authorizationStatus != .authorized {//未开启通知打开设置
|
||||
if #available(iOS 16.0, *) {
|
||||
if let url = URL(string: UIApplication.openNotificationSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
} else {
|
||||
if let url = URL(string: UIApplication.openSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
SPAPPTool.openApnsSetting()
|
||||
} else {//开启通知上报结果
|
||||
SPRewardsAPI.requestUploadOpenNotify(completer: nil)
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ class SPMineWalletView: UIView {
|
||||
view.backgroundColor = .colorFFFFFF(alpha: 0.06)
|
||||
view.layer.cornerRadius = 8
|
||||
view.layer.masksToBounds = true
|
||||
view.layer.borderWidth = 1
|
||||
view.layer.borderColor = UIColor.colorFFFFFF(alpha: 0.14).cgColor
|
||||
return view
|
||||
}()
|
||||
|
||||
|
@ -25,6 +25,9 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
|
||||
|
||||
private var detailModel: SPVideoDetailModel?
|
||||
|
||||
///上一次上报播放时长的节点
|
||||
private var lastUploadTime: Int = 0
|
||||
|
||||
//MARK: UI属性
|
||||
///选集视图
|
||||
private weak var episodeView: SPEpisodeView?
|
||||
@ -63,6 +66,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(buyVipFinishNotification), name: SPIAPManager.buyVipFinishNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||
|
||||
self.autoNextEpisode = true
|
||||
self.dataSource = self
|
||||
@ -102,7 +106,31 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
|
||||
|
||||
super.play()
|
||||
|
||||
SPVideoAPI.requestRequestVideoPlayHistory(videoId: videoInfo.short_play_video_id ?? "", shortPlayId: videoInfo.short_play_id ?? "")
|
||||
SPVideoAPI.requestCreateVideoPlayHistory(videoId: videoInfo.short_play_video_id ?? "", shortPlayId: videoInfo.short_play_id ?? "")
|
||||
}
|
||||
|
||||
override func currentPlayFinish() {
|
||||
if let videoInfo = self.viewModel.currentPlayer?.videoInfo, let activityId = self.activityId {
|
||||
//播放完成统计
|
||||
SPVideoAPI.requestViewingFinish(shortPlayId: videoInfo.short_play_id ?? "", videoId: videoInfo.short_play_video_id ?? "", activityId: activityId)
|
||||
}
|
||||
super.currentPlayFinish()
|
||||
}
|
||||
|
||||
override func currentPlayTimeDidChange(time: Int) {
|
||||
super.currentPlayTimeDidChange(time: time)
|
||||
let videoInfo = self.viewModel.currentPlayer?.videoInfo
|
||||
|
||||
|
||||
//每播放5秒上报一次 播放时长小于上次上报时间也需要上报
|
||||
if (time >= lastUploadTime + 5 || time < lastUploadTime) && time >= 5 {
|
||||
lastUploadTime = time
|
||||
|
||||
guard let shortPlayId = videoInfo?.short_play_id, let videoId = videoInfo?.short_play_video_id else { return }
|
||||
//上报播放时长
|
||||
SPVideoAPI.requestUploadPlayTime(shortPlayId: shortPlayId, videoId: videoId, seconds: time)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -220,6 +248,12 @@ extension SPPlayerDetailViewController {
|
||||
self?.play()
|
||||
}
|
||||
}
|
||||
///网络切换通知
|
||||
@objc private func reachabilityDidChangeNotification() {
|
||||
if SPNetworkReachabilityManager.manager.isReachable == true && self.detailModel == nil {
|
||||
self.requestDetailData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: -------------- SPPlayerListViewControllerDataSource --------------
|
||||
|
@ -217,6 +217,18 @@ class SPPlayerListViewController: SPViewController {
|
||||
self.collectionView.scrollToItem(at: indexPath, at: .top, animated: animated);
|
||||
CATransaction.commit()
|
||||
}
|
||||
|
||||
///当前播放完成 子类可重写
|
||||
func currentPlayFinish() {
|
||||
if self.autoNextEpisode {
|
||||
scrollToNextEpisode()
|
||||
}
|
||||
}
|
||||
|
||||
///当前播放进度变更 子类可重写
|
||||
func currentPlayTimeDidChange(time: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension SPPlayerListViewController {
|
||||
@ -242,6 +254,11 @@ extension SPPlayerListViewController {
|
||||
self?.currentPlayFinish()
|
||||
}
|
||||
|
||||
self.viewModel.handlePlayTimeDidChange = { [weak self] time in
|
||||
|
||||
self?.currentPlayTimeDidChange(time: time)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -267,12 +284,6 @@ extension SPPlayerListViewController {
|
||||
}
|
||||
}
|
||||
|
||||
///当前播放完成
|
||||
private func currentPlayFinish() {
|
||||
guard self.autoNextEpisode else { return }
|
||||
|
||||
scrollToNextEpisode()
|
||||
}
|
||||
|
||||
///滑动至下一级
|
||||
private func scrollToNextEpisode() {
|
||||
|
@ -197,6 +197,7 @@ extension SPPlayerListCell: SPPlayerDelegate {
|
||||
controlView.progress = CGFloat(currentTime) / CGFloat(duration)
|
||||
controlView.currentTime = currentTime
|
||||
controlView.durationTime = duration
|
||||
self.viewModel?.handlePlayTimeDidChange?(currentTime)
|
||||
}
|
||||
|
||||
func sp_firstRenderedStart(_ player: SPPlayer) {
|
||||
|
@ -46,6 +46,8 @@ class SPPlayerListViewModel: NSObject {
|
||||
var handlePauseOrPlay: (() -> Void)?
|
||||
///播放完成
|
||||
var handlePlayFinish: (() -> Void)?
|
||||
///播放进度变更
|
||||
var handlePlayTimeDidChange: ((_ time: Int) -> Void)?
|
||||
///选集
|
||||
var handleEpisode: (() -> Void)?
|
||||
|
||||
|
@ -94,3 +94,20 @@ extension SPAPPTool {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SPAPPTool {
|
||||
|
||||
///打开消息通知设置页面
|
||||
static func openApnsSetting() {
|
||||
if #available(iOS 16.0, *) {
|
||||
if let url = URL(string: UIApplication.openNotificationSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
} else {
|
||||
if let url = URL(string: UIApplication.openSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -103,6 +103,8 @@
|
||||
"kAlertMessage_01" = "The previous episode of this series has not been unlocked yet. Please unlock the previous episode first.";
|
||||
///没有找到视频提示
|
||||
"kAlertMessage_02" = "Purchase failed, please try again later!";
|
||||
///推送消息提示
|
||||
"kAlertMessage_03" = "Go and enable push messages?";
|
||||
|
||||
|
||||
"kLoginAgreementText" = "By continuing, you agree to the User Agreement and Privacy Policy";
|
||||
|
Loading…
x
Reference in New Issue
Block a user