W2A开发,各种统计
This commit is contained in:
parent
2bbfb16139
commit
94e047a0e9
@ -45,9 +45,20 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
|
|||||||
UIApplication.shared.applicationIconBadgeNumber = 0
|
UIApplication.shared.applicationIconBadgeNumber = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
let userInfo = response.notification.request.content.userInfo
|
guard let userInfo: [String : Any] = response.notification.request.content.userInfo as? [String : Any] else {
|
||||||
|
completionHandler()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let model = SPOpenAppModel.deserialize(from: userInfo) else {
|
||||||
|
completionHandler()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
SPStatAPI.requestStatApns(messageId: model.message_id ?? "", title: response.notification.request.content.title)
|
||||||
|
|
||||||
|
|
||||||
|
if let shortPlayId = model.short_play_id {
|
||||||
|
|
||||||
if let shortPlayId = userInfo["short_play_id"] as? String {
|
|
||||||
let vc = SPPlayerDetailViewController()
|
let vc = SPPlayerDetailViewController()
|
||||||
vc.shortPlayId = shortPlayId
|
vc.shortPlayId = shortPlayId
|
||||||
SPAPPTool.topViewController()?.navigationController?.pushViewController(vc, animated: true)
|
SPAPPTool.topViewController()?.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
@ -30,9 +30,61 @@ extension SceneDelegate {
|
|||||||
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
||||||
guard let webpageURL = userActivity.webpageURL else { return }
|
guard let webpageURL = userActivity.webpageURL else { return }
|
||||||
|
|
||||||
guard let query = webpageURL.query else { return }
|
handleOpenAppMessage(webpageURL: webpageURL)
|
||||||
|
}
|
||||||
spLog(message: query)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension SceneDelegate {
|
||||||
|
static var hasOpenMessage = false
|
||||||
|
|
||||||
|
func handleOpenAppMessage(webpageURL: URL?) {
|
||||||
|
|
||||||
|
//统计用URL
|
||||||
|
var statUrlStr: String?
|
||||||
|
var data: [String : Any]?
|
||||||
|
|
||||||
|
if let pasteStr = UIPasteboard.general.string {
|
||||||
|
UIPasteboard.general.string = nil
|
||||||
|
let tempArr = pasteStr.components(separatedBy: "?")
|
||||||
|
let query = tempArr.last
|
||||||
|
|
||||||
|
let tempData = query?.urlQuryToDictionary()
|
||||||
|
if tempData?["short_play_id"] != nil {
|
||||||
|
data = tempData
|
||||||
|
statUrlStr = pasteStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if Self.hasOpenMessage {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||||
|
Self.hasOpenMessage = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Self.hasOpenMessage = true
|
||||||
|
|
||||||
|
|
||||||
|
if data == nil {
|
||||||
|
data = webpageURL?.query?.urlQuryToDictionary()
|
||||||
|
statUrlStr = webpageURL?.absoluteString
|
||||||
|
}
|
||||||
|
|
||||||
|
if let urlStr = statUrlStr {//上报结果
|
||||||
|
SPStatAPI.requestStatW2a(data: urlStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
guard let data = data else { return }
|
||||||
|
guard let model = SPOpenAppModel.deserialize(from: data) else { return }
|
||||||
|
guard let shortPlayId = model.short_play_id, shortPlayId.count > 0 else { return }
|
||||||
|
|
||||||
|
|
||||||
|
let vc = SPPlayerDetailViewController()
|
||||||
|
vc.shortPlayId = shortPlayId
|
||||||
|
SPAPPTool.topViewController()?.navigationController?.pushViewController(vc, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ extension AppDelegate {
|
|||||||
|
|
||||||
|
|
||||||
private func registAdjust() {
|
private func registAdjust() {
|
||||||
let config = ADJConfig(appToken: "mtogye6pmha8", environment: ADJEnvironmentProduction)
|
let config = ADJConfig(appToken: "7z38v0rvceww", environment: ADJEnvironmentProduction)
|
||||||
Adjust.initSdk(config)
|
Adjust.initSdk(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
|
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
|
private var timer: Timer?
|
||||||
|
|
||||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||||
guard let windowScene = (scene as? UIWindowScene) else { return }
|
guard let windowScene = (scene as? UIWindowScene) else { return }
|
||||||
@ -20,6 +21,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
window = UIWindow(windowScene: windowScene)
|
window = UIWindow(windowScene: windowScene)
|
||||||
window?.rootViewController = tabBarController
|
window?.rootViewController = tabBarController
|
||||||
window?.makeKeyAndVisible()
|
window?.makeKeyAndVisible()
|
||||||
|
|
||||||
|
if let webpageURL = session.stateRestorationActivity?.webpageURL {
|
||||||
|
handleOpenAppMessage(webpageURL: webpageURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
//在线状态统计
|
||||||
|
timer = Timer.scheduledTimer(timeInterval: 60 * 10, target: self, selector: #selector(handleOnLine), userInfo: nil, repeats: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sceneDidDisconnect(_ scene: UIScene) {
|
func sceneDidDisconnect(_ scene: UIScene) {
|
||||||
@ -32,6 +40,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||||
// Called when the scene has moved from an inactive state to an active state.
|
// 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.
|
// 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) {
|
func sceneWillResignActive(_ scene: UIScene) {
|
||||||
@ -42,14 +52,23 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||||
// Called as the scene transitions from the background to the foreground.
|
// Called as the scene transitions from the background to the foreground.
|
||||||
// Use this method to undo the changes made on entering the background.
|
// Use this method to undo the changes made on entering the background.
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sceneDidEnterBackground(_ scene: UIScene) {
|
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||||
// Called as the scene transitions from the foreground to the background.
|
// Called as the scene transitions from the foreground to the background.
|
||||||
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||||
// to restore the scene back to its current state.
|
// to restore the scene back to its current state.
|
||||||
|
SPStatAPI.requestLeaveApp()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SceneDelegate {
|
||||||
|
|
||||||
|
@objc private func handleOnLine() {
|
||||||
|
SPStatAPI.requestStatOnLine()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,6 +33,25 @@ extension String: SmartCodable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
///将url中的参数转换成字典
|
||||||
|
func urlQuryToDictionary() -> [String : Any] {
|
||||||
|
let array = self.components(separatedBy: "&")
|
||||||
|
var tempDic: [String : Any] = [:]
|
||||||
|
|
||||||
|
array.forEach {
|
||||||
|
if let strRange = $0.range(of: "=") {
|
||||||
|
var key: String = String($0.prefix(upTo: strRange.upperBound))
|
||||||
|
key.removeLast()
|
||||||
|
var value: String = String($0.suffix(from: strRange.upperBound))
|
||||||
|
value = value.removingPercentEncoding ?? value
|
||||||
|
tempDic[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tempDic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension String {
|
extension String {
|
||||||
///获取文字Size
|
///获取文字Size
|
||||||
func size(font: UIFont, size: CGSize = CGSize(width: CGFloat(MAXFLOAT), height: CGFloat(MAXFLOAT))) -> CGSize{
|
func size(font: UIFont, size: CGSize = CGSize(width: CGFloat(MAXFLOAT), height: CGFloat(MAXFLOAT))) -> CGSize{
|
||||||
|
@ -388,5 +388,13 @@ extension UIColor {
|
|||||||
static func color362020(alpha: CGFloat = 1) -> UIColor {
|
static func color362020(alpha: CGFloat = 1) -> UIColor {
|
||||||
return color(hex: 0x362020, alpha: alpha)
|
return color(hex: 0x362020, alpha: alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func color7A7F96(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x7A7F96, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color967A7A(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x967A7A, alpha: alpha)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
MoviaBox/Base/Model/SPOpenAppModel.swift
Normal file
17
MoviaBox/Base/Model/SPOpenAppModel.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// SPOpenAppModel.swift
|
||||||
|
// MoviaBox
|
||||||
|
//
|
||||||
|
// Created by 佳尔 on 2025/5/8.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
|
class SPOpenAppModel: SPModel, SmartCodable {
|
||||||
|
|
||||||
|
var id: String?
|
||||||
|
var message_id: String?
|
||||||
|
var short_play_id: String?
|
||||||
|
|
||||||
|
}
|
75
MoviaBox/Base/Networking/API/SPStatAPI.swift
Normal file
75
MoviaBox/Base/Networking/API/SPStatAPI.swift
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// SPStatAPI.swift
|
||||||
|
// MoviaBox
|
||||||
|
//
|
||||||
|
// Created by 佳尔 on 2025/5/8.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
///统计
|
||||||
|
class SPStatAPI: NSObject {
|
||||||
|
|
||||||
|
///进入APP
|
||||||
|
static func requestEnterApp() {
|
||||||
|
|
||||||
|
var param = SPNetworkParameters(path: "/customer/enterTheApp")
|
||||||
|
param.isToast = false
|
||||||
|
param.isLoding = false
|
||||||
|
|
||||||
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///离开APP
|
||||||
|
static func requestLeaveApp() {
|
||||||
|
var param = SPNetworkParameters(path: "/customer/leaveApp")
|
||||||
|
param.isToast = false
|
||||||
|
param.isLoding = false
|
||||||
|
|
||||||
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///在线状态统计
|
||||||
|
static func requestStatOnLine() {
|
||||||
|
var param = SPNetworkParameters(path: "/customer/onLine")
|
||||||
|
param.isToast = false
|
||||||
|
param.isLoding = false
|
||||||
|
|
||||||
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///统计w2a点击
|
||||||
|
static func requestStatW2a(data: String) {
|
||||||
|
var param = SPNetworkParameters(path: "/w2aSelfAttribution")
|
||||||
|
param.isToast = false
|
||||||
|
param.isLoding = false
|
||||||
|
param.parameters = [
|
||||||
|
"data" : data
|
||||||
|
]
|
||||||
|
|
||||||
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///统计点击推送消息
|
||||||
|
static func requestStatApns(messageId: String, title: String) {
|
||||||
|
var param = SPNetworkParameters(path: "/message/sendReport")
|
||||||
|
param.isToast = false
|
||||||
|
param.isLoding = false
|
||||||
|
param.parameters = [
|
||||||
|
"message_id" : messageId,
|
||||||
|
"title" : title
|
||||||
|
]
|
||||||
|
|
||||||
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -54,16 +54,20 @@ class SPNetworkReachabilityManager {
|
|||||||
if path.status == .satisfied {
|
if path.status == .satisfied {
|
||||||
if self.isReachable == false {
|
if self.isReachable == false {
|
||||||
print("++++++有网")
|
print("++++++有网")
|
||||||
|
self.isReachable = true
|
||||||
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||||
|
} else {
|
||||||
|
self.isReachable = true
|
||||||
}
|
}
|
||||||
self.isReachable = true
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if self.isReachable == true {
|
if self.isReachable == true {
|
||||||
print("++++++无网")
|
print("++++++无网")
|
||||||
|
self.isReachable = false
|
||||||
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||||
|
} else {
|
||||||
|
self.isReachable = false
|
||||||
}
|
}
|
||||||
self.isReachable = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if path.usesInterfaceType(.wifi) {
|
// if path.usesInterfaceType(.wifi) {
|
||||||
|
@ -12,8 +12,9 @@ class SPHomeViewController: SPHomeChildController {
|
|||||||
|
|
||||||
private lazy var viewModel: SPHomeViewModel = SPHomeViewModel()
|
private lazy var viewModel: SPHomeViewModel = SPHomeViewModel()
|
||||||
|
|
||||||
private lazy var page = 1
|
|
||||||
private lazy var dataArr: [SPShortModel] = []
|
|
||||||
|
private lazy var requestGroup = DispatchGroup()
|
||||||
|
|
||||||
//MARK: UI属性
|
//MARK: UI属性
|
||||||
private lazy var logoImageView: UIImageView = {
|
private lazy var logoImageView: UIImageView = {
|
||||||
@ -64,6 +65,7 @@ class SPHomeViewController: SPHomeChildController {
|
|||||||
|
|
||||||
|
|
||||||
updateAllData(completer: nil)
|
updateAllData(completer: nil)
|
||||||
|
// updateEmptyState()
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
|
|
||||||
@ -89,7 +91,7 @@ class SPHomeViewController: SPHomeChildController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func handleFooterRefresh(_ completer: (() -> Void)?) {
|
override func handleFooterRefresh(_ completer: (() -> Void)?) {
|
||||||
requestListDataArr(page: self.page + 1) { [weak self] in
|
requestListDataArr(page: self.viewModel.page + 1) { [weak self] in
|
||||||
self?.collectionView.sp_endFooterRefreshing()
|
self?.collectionView.sp_endFooterRefreshing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,6 +137,18 @@ extension SPHomeViewController {
|
|||||||
updateAllData(completer: nil)
|
updateAllData(completer: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
///更新空白页面状态
|
||||||
|
private func updateEmptyState() {
|
||||||
|
|
||||||
|
if SPNetworkReachabilityManager.manager.isReachable != true, viewModel.isEmptyData {
|
||||||
|
self.collectionView.showNoNetworkEmpty { [weak self] in
|
||||||
|
self?.updateAllData(completer: nil)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.collectionView.hiddenEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,13 +157,13 @@ extension SPHomeViewController: UICollectionViewDelegate, UICollectionViewDataSo
|
|||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
let cell = SPHomeShortCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
let cell = SPHomeShortCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
||||||
cell.model = dataArr[indexPath.row]
|
cell.model = viewModel.dataArr[indexPath.row]
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
return dataArr.count
|
return viewModel.dataArr.count
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
|
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
|
||||||
@ -161,7 +175,7 @@ extension SPHomeViewController: UICollectionViewDelegate, UICollectionViewDataSo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
let model = self.dataArr[indexPath.row]
|
let model = viewModel.dataArr[indexPath.row]
|
||||||
|
|
||||||
let vc = SPPlayerDetailViewController()
|
let vc = SPPlayerDetailViewController()
|
||||||
vc.shortPlayId = model.short_play_id
|
vc.shortPlayId = model.short_play_id
|
||||||
@ -174,14 +188,25 @@ extension SPHomeViewController: UICollectionViewDelegate, UICollectionViewDataSo
|
|||||||
|
|
||||||
extension SPHomeViewController {
|
extension SPHomeViewController {
|
||||||
private func updateAllData(completer: (() -> Void)?) {
|
private func updateAllData(completer: (() -> Void)?) {
|
||||||
requestModuleData()
|
self.requestGroup.enter()
|
||||||
requestPlayHistory()
|
requestModuleData { [weak self] in
|
||||||
requestListDataArr(page: 1) {
|
self?.requestGroup.leave()
|
||||||
|
}
|
||||||
|
self.requestGroup.enter()
|
||||||
|
requestPlayHistory { [weak self] in
|
||||||
|
self?.requestGroup.leave()
|
||||||
|
}
|
||||||
|
self.requestGroup.enter()
|
||||||
|
requestListDataArr(page: 1) { [weak self] in
|
||||||
|
self?.requestGroup.leave()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requestGroup.notify(queue: DispatchQueue.main) {
|
||||||
completer?()
|
completer?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func requestModuleData() {
|
private func requestModuleData(completer: (() -> Void)? = nil) {
|
||||||
SPHomeAPI.requestHomeModuleData { [weak self] model in
|
SPHomeAPI.requestHomeModuleData { [weak self] model in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
if let model = model {
|
if let model = model {
|
||||||
@ -190,11 +215,13 @@ extension SPHomeViewController {
|
|||||||
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
}
|
}
|
||||||
|
self.updateEmptyState()
|
||||||
|
completer?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///获取播放记录
|
///获取播放记录
|
||||||
private func requestPlayHistory() {
|
private func requestPlayHistory(completer: (() -> Void)? = nil) {
|
||||||
SPVideoAPI.requestPlayHistoryList(page: 1) { [weak self] listModel in
|
SPVideoAPI.requestPlayHistoryList(page: 1) { [weak self] listModel in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
if let list = listModel?.list {
|
if let list = listModel?.list {
|
||||||
@ -202,6 +229,8 @@ extension SPHomeViewController {
|
|||||||
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
}
|
}
|
||||||
|
self.updateEmptyState()
|
||||||
|
completer?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,13 +241,14 @@ extension SPHomeViewController {
|
|||||||
|
|
||||||
if let list = listModel?.list {
|
if let list = listModel?.list {
|
||||||
if page == 1 {
|
if page == 1 {
|
||||||
self.dataArr.removeAll()
|
self.viewModel.dataArr.removeAll()
|
||||||
}
|
}
|
||||||
self.dataArr += list
|
self.viewModel.dataArr += list
|
||||||
|
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
self.page = page
|
self.viewModel.page = page
|
||||||
}
|
}
|
||||||
|
self.updateEmptyState()
|
||||||
completer?()
|
completer?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,11 @@ class SPHomeHeaderView: UICollectionReusableView {
|
|||||||
|
|
||||||
stackView.removeAllArrangedSubview()
|
stackView.removeAllArrangedSubview()
|
||||||
|
|
||||||
stackView.addArrangedSubview(bannerView)
|
|
||||||
bannerView.reloadData()
|
if let bannerData = moduleModel?.bannerData, bannerData.count > 0 {
|
||||||
|
stackView.addArrangedSubview(bannerView)
|
||||||
|
bannerView.reloadData()
|
||||||
|
}
|
||||||
|
|
||||||
if let historyList = viewModel?.playHistoryArr, historyList.count > 0 {
|
if let historyList = viewModel?.playHistoryArr, historyList.count > 0 {
|
||||||
stackView.addArrangedSubview(playHistoryView)
|
stackView.addArrangedSubview(playHistoryView)
|
||||||
@ -200,18 +203,27 @@ extension SPHomeHeaderView: ZKCycleScrollViewDelegate, ZKCycleScrollViewDataSour
|
|||||||
extension SPHomeHeaderView {
|
extension SPHomeHeaderView {
|
||||||
|
|
||||||
static func contentHeight(viewModel: SPHomeViewModel) -> CGFloat {
|
static func contentHeight(viewModel: SPHomeViewModel) -> CGFloat {
|
||||||
var height = bannerHeight()
|
var height: CGFloat = 0
|
||||||
let moduleModel = viewModel.moduleModel
|
let moduleModel = viewModel.moduleModel
|
||||||
|
|
||||||
|
if let bannerData = moduleModel?.bannerData, bannerData.count > 0 {
|
||||||
|
height = height + bannerHeight()
|
||||||
|
}
|
||||||
|
|
||||||
///历史记录
|
///历史记录
|
||||||
if let historyList = viewModel.playHistoryArr, historyList.count > 0 {
|
if let historyList = viewModel.playHistoryArr, historyList.count > 0 {
|
||||||
height = height + SPHomePlayHistoryView.contentHeight(dataArr: historyList) + 25
|
if height > 0 {
|
||||||
|
height = height + 25
|
||||||
|
}
|
||||||
|
height = height + SPHomePlayHistoryView.contentHeight(dataArr: historyList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///九宫格数据
|
///九宫格数据
|
||||||
if let list = moduleModel?.nineSquare?.list, list.count > 0 {
|
if let list = moduleModel?.nineSquare?.list, list.count > 0 {
|
||||||
height = height + SPHomeExploreView.contentHeight(dataArr: list) + 25
|
if height > 0 {
|
||||||
|
height = height + 25
|
||||||
|
}
|
||||||
|
height = height + SPHomeExploreView.contentHeight(dataArr: list)
|
||||||
}
|
}
|
||||||
|
|
||||||
// height = height + SPHomeTrendingView.contentHeight(dataArr: moduleModel?.bannerData ?? []) + 25
|
// height = height + SPHomeTrendingView.contentHeight(dataArr: moduleModel?.bannerData ?? []) + 25
|
||||||
|
@ -24,6 +24,7 @@ class SPSearchAssociativeView: UIView {
|
|||||||
tableView.separatorInset = .init(top: 0, left: 16, bottom: 0, right: 16)
|
tableView.separatorInset = .init(top: 0, left: 16, bottom: 0, right: 16)
|
||||||
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
||||||
tableView.keyboardDismissMode = .onDrag
|
tableView.keyboardDismissMode = .onDrag
|
||||||
|
tableView.showNormalEmpty(image: UIImage(named: "empty_image_03"))
|
||||||
SPSearchAssociativeCell.registerCell(tableView: tableView)
|
SPSearchAssociativeCell.registerCell(tableView: tableView)
|
||||||
return tableView
|
return tableView
|
||||||
}()
|
}()
|
||||||
|
@ -9,11 +9,20 @@ import UIKit
|
|||||||
|
|
||||||
class SPHomeViewModel: NSObject {
|
class SPHomeViewModel: NSObject {
|
||||||
|
|
||||||
|
lazy var page = 1
|
||||||
|
lazy var dataArr: [SPShortModel] = []
|
||||||
|
|
||||||
var moduleModel: SPHomeModuleModel?
|
var moduleModel: SPHomeModuleModel?
|
||||||
|
|
||||||
///历史记录
|
///历史记录
|
||||||
var playHistoryArr: [SPShortModel]?
|
var playHistoryArr: [SPShortModel]?
|
||||||
|
|
||||||
|
|
||||||
|
var isEmptyData: Bool {
|
||||||
|
if dataArr.count > 0 || (playHistoryArr?.count ?? 0) > 0 || moduleModel != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ class SPCollectListViewController: SPMyListChildViewController {
|
|||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
collectionView.dataSource = self
|
collectionView.dataSource = self
|
||||||
collectionView.contentInset = .init(top: 10, left: 0, bottom: 0, right: 0)
|
collectionView.contentInset = .init(top: 10, left: 0, bottom: 0, right: 0)
|
||||||
|
collectionView.showNormalEmpty()
|
||||||
collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in
|
collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in
|
||||||
self?.handleHeaderRefresh(nil)
|
self?.handleHeaderRefresh(nil)
|
||||||
}
|
}
|
||||||
@ -148,11 +149,6 @@ extension SPCollectListViewController: UICollectionViewDelegate, UICollectionVie
|
|||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
let count = self.dataArr.count
|
let count = self.dataArr.count
|
||||||
if count == 0 {
|
|
||||||
self.collectionView.addNormalEmpty()
|
|
||||||
} else {
|
|
||||||
self.collectionView.hiddenEmpty()
|
|
||||||
}
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,13 @@ class SPMyListViewController: SPViewController {
|
|||||||
return pageView
|
return pageView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private(set) lazy var wmPageView: WMPageController = {
|
||||||
|
let pageView = WMPageController()
|
||||||
|
pageView.delegate = self
|
||||||
|
pageView.dataSource = self
|
||||||
|
return pageView
|
||||||
|
}()
|
||||||
|
|
||||||
private lazy var editButton: UIButton = {
|
private lazy var editButton: UIButton = {
|
||||||
let button = UIButton(type: .custom)
|
let button = UIButton(type: .custom)
|
||||||
button.setImage(UIImage(named: "delete_icon_01"), for: .normal)
|
button.setImage(UIImage(named: "delete_icon_01"), for: .normal)
|
||||||
@ -145,9 +152,11 @@ class SPMyListViewController: SPViewController {
|
|||||||
extension SPMyListViewController {
|
extension SPMyListViewController {
|
||||||
private func _setupUI() {
|
private func _setupUI() {
|
||||||
addChild(pageView)
|
addChild(pageView)
|
||||||
|
// addChild(self.wmPageView)
|
||||||
|
|
||||||
view.addSubview(lineView)
|
view.addSubview(lineView)
|
||||||
view.addSubview(pageView.view)
|
view.addSubview(pageView.view)
|
||||||
|
// view.addSubview(wmPageView.view)
|
||||||
view.addSubview(editButton)
|
view.addSubview(editButton)
|
||||||
view.addSubview(cancelButton)
|
view.addSubview(cancelButton)
|
||||||
// view.addSubview(allSelectedButton)
|
// view.addSubview(allSelectedButton)
|
||||||
@ -182,6 +191,40 @@ extension SPMyListViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: -------------- WMPageControllerDelegate & WMPageControllerDataSource --------------
|
||||||
|
extension SPMyListViewController: WMPageControllerDelegate, WMPageControllerDataSource {
|
||||||
|
|
||||||
|
func pageController(_ pageController: WMPageController, preferredFrameForContentView contentView: WMScrollView) -> CGRect {
|
||||||
|
let y = kSPStatusbarHeight + 10 + 35
|
||||||
|
return .init(x: 0, y: kSPStatusbarHeight + 10 + 35, width: kSPScreenWidth, height: kSPScreenHeight - y - kSPTabBarHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageController(_ pageController: WMPageController, preferredFrameFor menuView: WMMenuView) -> CGRect {
|
||||||
|
return .init(x: 0, y: kSPStatusbarHeight + 10, width: kSPScreenWidth, height: 35)
|
||||||
|
}
|
||||||
|
|
||||||
|
func numbersOfChildControllers(in pageController: WMPageController) -> Int {
|
||||||
|
return titles.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageController(_ pageController: WMPageController, titleAt index: Int) -> String {
|
||||||
|
return titles[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageController(_ pageController: WMPageController, viewControllerAt index: Int) -> UIViewController {
|
||||||
|
self.viewControllers[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageController(_ pageController: WMPageController, didEnter viewController: UIViewController, withInfo info: [AnyHashable : Any]) {
|
||||||
|
if pageController.selectIndex == 0 {
|
||||||
|
self.editButton.isHidden = false
|
||||||
|
} else {
|
||||||
|
self.editButton.isHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//MARK: -------------- JYPageControllerDelegate & JYPageControllerDataSource --------------
|
//MARK: -------------- JYPageControllerDelegate & JYPageControllerDataSource --------------
|
||||||
extension SPMyListViewController: JYPageControllerDelegate, JYPageControllerDataSource {
|
extension SPMyListViewController: JYPageControllerDelegate, JYPageControllerDataSource {
|
||||||
|
@ -32,6 +32,7 @@ class SPPlayHistoryViewController: SPMyListChildViewController {
|
|||||||
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
collectionView.dataSource = self
|
collectionView.dataSource = self
|
||||||
|
collectionView.showNormalEmpty()
|
||||||
collectionView.contentInset = .init(top: 10, left: 0, bottom: 0, right: 0)
|
collectionView.contentInset = .init(top: 10, left: 0, bottom: 0, right: 0)
|
||||||
collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in
|
collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in
|
||||||
self?.handleHeaderRefresh(nil)
|
self?.handleHeaderRefresh(nil)
|
||||||
@ -143,13 +144,6 @@ extension SPPlayHistoryViewController: UICollectionViewDelegate, UICollectionVie
|
|||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
let count = self.dataArr.count
|
let count = self.dataArr.count
|
||||||
|
|
||||||
if count == 0 {
|
|
||||||
self.collectionView.addNormalEmpty()
|
|
||||||
} else {
|
|
||||||
self.collectionView.hiddenEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +198,8 @@ extension SPPlayerDetailViewController {
|
|||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.play()
|
self.play()
|
||||||
}
|
}
|
||||||
|
//更新用户信息
|
||||||
|
SPLoginManager.manager.updateUserInfo(completer: nil)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
@ -19,6 +19,7 @@ class SPCoinOrderRecordViewController: SPViewController {
|
|||||||
tableView.delegate = self
|
tableView.delegate = self
|
||||||
tableView.dataSource = self
|
tableView.dataSource = self
|
||||||
tableView.rowHeight = 70
|
tableView.rowHeight = 70
|
||||||
|
tableView.showNormalEmpty()
|
||||||
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
||||||
tableView.sp_addRefreshHeader { [weak self] in
|
tableView.sp_addRefreshHeader { [weak self] in
|
||||||
self?.handleHeaderRefresh(nil)
|
self?.handleHeaderRefresh(nil)
|
||||||
@ -76,11 +77,6 @@ extension SPCoinOrderRecordViewController: UITableViewDelegate, UITableViewDataS
|
|||||||
|
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
let count = self.dataArr.count
|
let count = self.dataArr.count
|
||||||
if count == 0 {
|
|
||||||
self.tableView.addNormalEmpty()
|
|
||||||
} else {
|
|
||||||
self.tableView.hiddenEmpty()
|
|
||||||
}
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ class SPConsumptionRecordsViewController: SPViewController {
|
|||||||
tableView.delegate = self
|
tableView.delegate = self
|
||||||
tableView.dataSource = self
|
tableView.dataSource = self
|
||||||
tableView.rowHeight = 72
|
tableView.rowHeight = 72
|
||||||
|
tableView.showNormalEmpty()
|
||||||
tableView.separatorInset = .init(top: 0, left: 32, bottom: 0, right: 32)
|
tableView.separatorInset = .init(top: 0, left: 32, bottom: 0, right: 32)
|
||||||
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
||||||
tableView.sp_addRefreshHeader { [weak self] in
|
tableView.sp_addRefreshHeader { [weak self] in
|
||||||
@ -82,11 +83,6 @@ extension SPConsumptionRecordsViewController: UITableViewDelegate, UITableViewDa
|
|||||||
|
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
let count = self.dataArr.count
|
let count = self.dataArr.count
|
||||||
if count == 0 {
|
|
||||||
self.tableView.addNormalEmpty()
|
|
||||||
} else {
|
|
||||||
self.tableView.hiddenEmpty()
|
|
||||||
}
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ class SPRewardCoinsViewController: SPViewController {
|
|||||||
tableView.delegate = self
|
tableView.delegate = self
|
||||||
tableView.dataSource = self
|
tableView.dataSource = self
|
||||||
tableView.rowHeight = 96
|
tableView.rowHeight = 96
|
||||||
|
tableView.showNormalEmpty()
|
||||||
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
||||||
tableView.sp_addRefreshHeader { [weak self] in
|
tableView.sp_addRefreshHeader { [weak self] in
|
||||||
self?.handleHeaderRefresh(nil)
|
self?.handleHeaderRefresh(nil)
|
||||||
@ -84,11 +85,6 @@ extension SPRewardCoinsViewController: UITableViewDelegate, UITableViewDataSourc
|
|||||||
|
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
let count = self.dataArr.count
|
let count = self.dataArr.count
|
||||||
if count == 0 {
|
|
||||||
self.tableView.addNormalEmpty()
|
|
||||||
} else {
|
|
||||||
self.tableView.hiddenEmpty()
|
|
||||||
}
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ class SPVIPOrderRecordViewController: SPViewController {
|
|||||||
tableView.delegate = self
|
tableView.delegate = self
|
||||||
tableView.dataSource = self
|
tableView.dataSource = self
|
||||||
tableView.rowHeight = 74
|
tableView.rowHeight = 74
|
||||||
|
tableView.showNormalEmpty()
|
||||||
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
||||||
tableView.sp_addRefreshHeader { [weak self] in
|
tableView.sp_addRefreshHeader { [weak self] in
|
||||||
self?.handleHeaderRefresh(nil)
|
self?.handleHeaderRefresh(nil)
|
||||||
@ -75,11 +76,6 @@ extension SPVIPOrderRecordViewController: UITableViewDelegate, UITableViewDataSo
|
|||||||
|
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
let count = self.dataArr.count
|
let count = self.dataArr.count
|
||||||
if count == 0 {
|
|
||||||
self.tableView.addNormalEmpty()
|
|
||||||
} else {
|
|
||||||
self.tableView.hiddenEmpty()
|
|
||||||
}
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
//
|
|
||||||
// SPEmptyState.swift
|
|
||||||
// MoviaBox
|
|
||||||
//
|
|
||||||
// Created by Overseas on 2025/4/19.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import EmptyStateKit
|
|
||||||
|
|
||||||
struct SPEmptyParameters {
|
|
||||||
// var title: String = "暂无内容"
|
|
||||||
// var titleFont: UIFont = UIFont.text_md
|
|
||||||
// var titleColor: UIColor = UIColor.system_text_secondary_300
|
|
||||||
var image: UIImage? = UIImage(named: "empty_image_01")
|
|
||||||
// var buttonTitle: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SPEmptyState {
|
|
||||||
case normail(parameters: SPEmptyParameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPEmptyState: CustomState {
|
|
||||||
|
|
||||||
var image: UIImage? {
|
|
||||||
switch self {
|
|
||||||
case .normail(let parameters):
|
|
||||||
return parameters.image
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var title: String? {
|
|
||||||
switch self {
|
|
||||||
case .normail(_):
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// var titleButton: String? {
|
|
||||||
// switch self {
|
|
||||||
// case .normail(let parameters):
|
|
||||||
// return parameters.buttonTitle
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPEmptyState {
|
|
||||||
var format: EmptyStateFormat {
|
|
||||||
|
|
||||||
var format = EmptyStateFormat()
|
|
||||||
format.backgroundColor = .clear
|
|
||||||
format.imageSize = self.image?.size ?? .zero
|
|
||||||
format.animation = nil
|
|
||||||
format.verticalMargin = -50
|
|
||||||
//
|
|
||||||
// format.buttonWidth = 107
|
|
||||||
// format.buttonTopMargin = 10
|
|
||||||
// format.buttonColor = .system_fill_primary_100
|
|
||||||
// format.buttonAttributes = [
|
|
||||||
// .font: UIFont.text_md,
|
|
||||||
// .foregroundColor: UIColor.system_text_secondary_500
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
// switch self {
|
|
||||||
// case .normail(let p):
|
|
||||||
// format.titleAttributes = [
|
|
||||||
// .font: p.titleFont,
|
|
||||||
// .foregroundColor: p.titleColor
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// case .login(let p):
|
|
||||||
// format.titleAttributes = [
|
|
||||||
// .font: p.titleFont,
|
|
||||||
// .foregroundColor: p.titleColor
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return format
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
90
MoviaBox/Libs/Empty/SPNoNetworkEmptyView.swift
Normal file
90
MoviaBox/Libs/Empty/SPNoNetworkEmptyView.swift
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// SPNoNetworkEmptyView.swift
|
||||||
|
// MoviaBox
|
||||||
|
//
|
||||||
|
// Created by 佳尔 on 2025/5/8.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPNoNetworkEmptyView: UIView {
|
||||||
|
|
||||||
|
|
||||||
|
override var intrinsicContentSize: CGSize {
|
||||||
|
return CGSize(width: kSPScreenWidth, height: 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
var clickButton: (() -> Void)?
|
||||||
|
|
||||||
|
//MARK: UI属性
|
||||||
|
private lazy var iconImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "empty_image_02"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontRegular(ofSize: 16)
|
||||||
|
label.textColor = .color967A7A()
|
||||||
|
label.text = "kNoNetworkTip_01".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var button: UIButton = {
|
||||||
|
let button = JXButton(type: .custom)
|
||||||
|
button.layer.cornerRadius = 17
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.layer.borderWidth = 1
|
||||||
|
button.layer.borderColor = UIColor.colorFFFFFF().cgColor
|
||||||
|
button.jx_font = .fontRegular(ofSize: 18)
|
||||||
|
button.setTitleColor(.colorFFFFFF(), for: .normal)
|
||||||
|
button.setTitle("Retry".localized, for: .normal)
|
||||||
|
button.leftAndRightMargin = 33
|
||||||
|
button.addTarget(self, action: #selector(handleButton), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handleButton() {
|
||||||
|
self.clickButton?()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPNoNetworkEmptyView {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
addSubview(iconImageView)
|
||||||
|
addSubview(titleLabel)
|
||||||
|
addSubview(button)
|
||||||
|
|
||||||
|
iconImageView.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(iconImageView.snp.bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
button.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(titleLabel.snp.bottom).offset(28)
|
||||||
|
make.height.equalTo(34)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -6,18 +6,47 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import EmptyDataSet_Swift
|
||||||
|
|
||||||
|
|
||||||
extension UIScrollView {
|
extension UIScrollView {
|
||||||
|
|
||||||
func addNormalEmpty() {
|
///展示一个普通的空白页
|
||||||
let parameters = SPEmptyParameters()
|
func showNormalEmpty(image: UIImage? = UIImage(named: "empty_image_01"), title: String? = nil, titleColor: UIColor? = nil) {
|
||||||
let emptyState = SPEmptyState.normail(parameters: parameters)
|
|
||||||
self.emptyState.format = emptyState.format
|
self.emptyDataSetView { view in
|
||||||
self.emptyState.show(emptyState)
|
view.image(image)
|
||||||
|
.isScrollAllowed(true)
|
||||||
|
.verticalOffset(-100)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///展示一个无网的空白页
|
||||||
|
func showNoNetworkEmpty(buttonHandle: (() -> Void)? = nil) {
|
||||||
|
|
||||||
|
let customView = SPNoNetworkEmptyView()
|
||||||
|
customView.clickButton = {
|
||||||
|
buttonHandle?()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.emptyDataSetView { view in
|
||||||
|
view.isScrollAllowed(true)
|
||||||
|
.customView(customView)
|
||||||
|
.verticalOffset(-70)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reloadEmptyDataSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func hiddenEmpty() {
|
func hiddenEmpty() {
|
||||||
self.emptyState.hide()
|
|
||||||
|
self.emptyDataSetView { view in
|
||||||
|
view.customView(nil)
|
||||||
|
view.image(nil)
|
||||||
|
view.titleLabelString(nil)
|
||||||
|
}
|
||||||
|
self.reloadEmptyDataSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>com.apple.developer.associated-domains</key>
|
<key>com.apple.developer.associated-domains</key>
|
||||||
<array>
|
<array>
|
||||||
<string>applinks:moviaboxapp.go.link</string>
|
<string>applinks:moviaapp.go.link</string>
|
||||||
<string>applinks:www.moviatv.com</string>
|
<string>applinks:www.moviatv.com</string>
|
||||||
</array>
|
</array>
|
||||||
<key>keychain-access-groups</key>
|
<key>keychain-access-groups</key>
|
||||||
|
22
MoviaBox/Source/Assets.xcassets/image/empty_image_02.imageset/Contents.json
vendored
Normal file
22
MoviaBox/Source/Assets.xcassets/image/empty_image_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "image 38@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "image 38@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_02.imageset/image 38@2x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_02.imageset/image 38@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_02.imageset/image 38@3x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_02.imageset/image 38@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
22
MoviaBox/Source/Assets.xcassets/image/empty_image_03.imageset/Contents.json
vendored
Normal file
22
MoviaBox/Source/Assets.xcassets/image/empty_image_03.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_03.imageset/Group@2x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_03.imageset/Group@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_03.imageset/Group@3x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/image/empty_image_03.imageset/Group@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -19,7 +19,7 @@
|
|||||||
<string>Editor</string>
|
<string>Editor</string>
|
||||||
<key>CFBundleURLSchemes</key>
|
<key>CFBundleURLSchemes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>MoviaTV</string>
|
<string>moviaapp</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
<dict/>
|
<dict/>
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
"Unlock now for" = "Unlock now for";
|
"Unlock now for" = "Unlock now for";
|
||||||
"Unlock the previous episode" = "Unlock the previous episode";
|
"Unlock the previous episode" = "Unlock the previous episode";
|
||||||
"Purchase Single Episode" = "Purchase Single Episode";
|
"Purchase Single Episode" = "Purchase Single Episode";
|
||||||
|
"Retry" = "Retry";
|
||||||
|
|
||||||
///没有可恢复购买
|
///没有可恢复购买
|
||||||
"kToastMessage_01" = "There are no recoverable in-app purchases.";
|
"kToastMessage_01" = "There are no recoverable in-app purchases.";
|
||||||
@ -109,4 +110,5 @@
|
|||||||
"kStoreTipTitle" = "Related terms and conditions:";
|
"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. ";
|
"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";
|
"kDeleteAccountCheckText" = "I accept the deletion risk and agree to delete my account";
|
||||||
|
"kNoNetworkTip_01" = "Connection error. Please try again!";
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public class JYScrollView: UITableView,UIGestureRecognizerDelegate {
|
public class JYScrollView: UITableView {
|
||||||
|
|
||||||
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||||
return gestureRecognizer.isKind(of: UIPanGestureRecognizer.classForCoder()) && otherGestureRecognizer.isKind(of: UIPanGestureRecognizer.classForCoder())
|
return gestureRecognizer.isKind(of: UIPanGestureRecognizer.classForCoder()) && otherGestureRecognizer.isKind(of: UIPanGestureRecognizer.classForCoder())
|
||||||
|
2
Podfile
2
Podfile
@ -26,7 +26,7 @@ target 'MoviaBox' do
|
|||||||
pod 'KTVHTTPCache' #视频缓存
|
pod 'KTVHTTPCache' #视频缓存
|
||||||
pod 'HWPanModal' #底部弹出控制器
|
pod 'HWPanModal' #底部弹出控制器
|
||||||
pod 'Kingfisher' #图片加载
|
pod 'Kingfisher' #图片加载
|
||||||
pod 'EmptyStateKit' #空数据页面
|
pod 'EmptyDataSet-Swift' #空数据页面
|
||||||
pod 'ReachabilitySwift' #网络状态监控
|
pod 'ReachabilitySwift' #网络状态监控
|
||||||
pod 'WMZPageController' #分页控制器
|
pod 'WMZPageController' #分页控制器
|
||||||
pod 'SVProgressHUD' #HUD
|
pod 'SVProgressHUD' #HUD
|
||||||
|
10
Podfile.lock
10
Podfile.lock
@ -6,7 +6,7 @@ PODS:
|
|||||||
- AdjustSignature (3.35.2)
|
- AdjustSignature (3.35.2)
|
||||||
- Alamofire (5.10.2)
|
- Alamofire (5.10.2)
|
||||||
- CocoaAsyncSocket (7.6.5)
|
- CocoaAsyncSocket (7.6.5)
|
||||||
- EmptyStateKit (1.1.0)
|
- EmptyDataSet-Swift (5.0.0)
|
||||||
- HWPanModal (0.9.9)
|
- HWPanModal (0.9.9)
|
||||||
- Kingfisher (8.3.2)
|
- Kingfisher (8.3.2)
|
||||||
- KTVHTTPCache (3.0.2):
|
- KTVHTTPCache (3.0.2):
|
||||||
@ -38,7 +38,7 @@ PODS:
|
|||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Adjust
|
- Adjust
|
||||||
- EmptyStateKit
|
- EmptyDataSet-Swift
|
||||||
- HWPanModal
|
- HWPanModal
|
||||||
- Kingfisher
|
- Kingfisher
|
||||||
- KTVHTTPCache
|
- KTVHTTPCache
|
||||||
@ -58,12 +58,12 @@ SPEC REPOS:
|
|||||||
https://github.com/CocoaPods/Specs.git:
|
https://github.com/CocoaPods/Specs.git:
|
||||||
- Adjust
|
- Adjust
|
||||||
- AdjustSignature
|
- AdjustSignature
|
||||||
|
- EmptyDataSet-Swift
|
||||||
- Kingfisher
|
- Kingfisher
|
||||||
- ZFPlayer
|
- ZFPlayer
|
||||||
trunk:
|
trunk:
|
||||||
- Alamofire
|
- Alamofire
|
||||||
- CocoaAsyncSocket
|
- CocoaAsyncSocket
|
||||||
- EmptyStateKit
|
|
||||||
- HWPanModal
|
- HWPanModal
|
||||||
- KTVHTTPCache
|
- KTVHTTPCache
|
||||||
- MJRefresh
|
- MJRefresh
|
||||||
@ -82,7 +82,7 @@ SPEC CHECKSUMS:
|
|||||||
AdjustSignature: 23b9e5d4adcadffc303bb6b410fde617dd88504f
|
AdjustSignature: 23b9e5d4adcadffc303bb6b410fde617dd88504f
|
||||||
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
||||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||||
EmptyStateKit: dc41e9ce5c6089f67a49d063bce73ade9f2ba73f
|
EmptyDataSet-Swift: eb382c0c87a2d9c678077385a595cec52da38171
|
||||||
HWPanModal: b57a6717d3cdcd666bff44f9dd2a5be9f4d6f5d2
|
HWPanModal: b57a6717d3cdcd666bff44f9dd2a5be9f4d6f5d2
|
||||||
Kingfisher: 0621d0ac0c78fecb19f6dc5303bde2b52abaf2f5
|
Kingfisher: 0621d0ac0c78fecb19f6dc5303bde2b52abaf2f5
|
||||||
KTVHTTPCache: 5711692cdf9a5ecfe829b1e16577deb3ffe3dc86
|
KTVHTTPCache: 5711692cdf9a5ecfe829b1e16577deb3ffe3dc86
|
||||||
@ -98,6 +98,6 @@ SPEC CHECKSUMS:
|
|||||||
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
|
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
|
||||||
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
|
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
|
||||||
|
|
||||||
PODFILE CHECKSUM: 2a79f81260b8df4d6be58f4acb217732b1cd49ab
|
PODFILE CHECKSUM: 1e8174e48a7218cf3eed0a059ee987d0638ab131
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"buildCommand" : {
|
||||||
|
"command" : "build",
|
||||||
|
"skipDependencies" : false,
|
||||||
|
"style" : "buildOnly"
|
||||||
|
},
|
||||||
|
"configuredTargets" : [
|
||||||
|
|
||||||
|
],
|
||||||
|
"continueBuildingAfterErrors" : false,
|
||||||
|
"dependencyScope" : "workspace",
|
||||||
|
"enableIndexBuildArena" : false,
|
||||||
|
"hideShellScriptEnvironment" : false,
|
||||||
|
"parameters" : {
|
||||||
|
"action" : "build",
|
||||||
|
"overrides" : {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"qos" : "default",
|
||||||
|
"schemeCommand" : "launch",
|
||||||
|
"showNonLoggedProgress" : true,
|
||||||
|
"useDryRun" : false,
|
||||||
|
"useImplicitDependencies" : false,
|
||||||
|
"useLegacyBuildLocations" : false,
|
||||||
|
"useParallelTargets" : true
|
||||||
|
}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
{"client":{"name":"basic","version":0,"file-system":"device-agnostic","perform-ownership-analysis":"no"},"targets":{"":["<all>"]},"commands":{"<all>":{"tool":"phony","inputs":["<WorkspaceHeaderMapVFSFilesWritten>"],"outputs":["<all>"]},"P0:::Gate WorkspaceHeaderMapVFSFilesWritten":{"tool":"phony","inputs":[],"outputs":["<WorkspaceHeaderMapVFSFilesWritten>"]}}}
|
@ -0,0 +1 @@
|
|||||||
|
Target dependency graph (0 target)
|
Binary file not shown.
6
证书秘钥/内购/SubscriptionKey_9TBBMA3N28.p8
Normal file
6
证书秘钥/内购/SubscriptionKey_9TBBMA3N28.p8
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgXR+Zedc3wF8TuJG6
|
||||||
|
oDKxJbcDqDLJDEx/ExfQKT5GMc+gCgYIKoZIzj0DAQehRANCAASNWCeIL6ELCoVo
|
||||||
|
igAm8yXBuraOuuQdbPBmJnFwauYq3pFZt3RiTKZxXLs3TAHXuuK6jlUMNZ0SsyIf
|
||||||
|
epUu2+ms
|
||||||
|
-----END PRIVATE KEY-----
|
6
证书秘钥/内购/SubscriptionKey_B4LXRNN96J-秘钥2.p8
Normal file
6
证书秘钥/内购/SubscriptionKey_B4LXRNN96J-秘钥2.p8
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIAZqlqn64s0g/cLK
|
||||||
|
HYv57T2s5WVllSrs6yyZeL0F1UegCgYIKoZIzj0DAQehRANCAATkoC81el02PBYY
|
||||||
|
0NtOiD6ZABY5yidgX7BLdfhIR4YABXRMHqgf5cC1wJeMFbuPimAhFyQUOjz4U3Pu
|
||||||
|
VYJ/uVUy
|
||||||
|
-----END PRIVATE KEY-----
|
2
证书秘钥/内购/秘钥.txt
Normal file
2
证书秘钥/内购/秘钥.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Issuer ID:5a4eda78-a1ec-4e14-b9e1-438e0c6b65e0
|
||||||
|
共享秘钥:ef592c2f58e544f7b64c9e8e3fbdd918
|
6
证书秘钥/团队秘钥/AuthKey_J5BTYX2VYL.p8
Normal file
6
证书秘钥/团队秘钥/AuthKey_J5BTYX2VYL.p8
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgcGOb1W3PIj7aFHCV
|
||||||
|
gklnxGt7MUXIwO8NGjxmYugvNqygCgYIKoZIzj0DAQehRANCAAT4GJv/flDfYucP
|
||||||
|
klNWB0Gbl4SC8g1aRQWsjlH5ZhTRCADsQMchLv1hfLluggscZ9/mjooXqxeIa9dA
|
||||||
|
kCEe5BH5
|
||||||
|
-----END PRIVATE KEY-----
|
6
证书秘钥/推送证书/AuthKey_RR837V244H.p8
Normal file
6
证书秘钥/推送证书/AuthKey_RR837V244H.p8
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgybyT4E9RcVHpanWn
|
||||||
|
rWHRf50TR8iio6SZ2s2oploN4JegCgYIKoZIzj0DAQehRANCAAQ4gRcELlsyQecH
|
||||||
|
Czr4kIVXbrD9oOk/ibNsSq7QpHSHgs8T+Ev08miNqPc9fMxP9KkIVgTxdKNdVkXg
|
||||||
|
g7cByXj5
|
||||||
|
-----END PRIVATE KEY-----
|
30
证书秘钥/推送证书/GoogleService-Info.plist
Normal file
30
证书秘钥/推送证书/GoogleService-Info.plist
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyAT78NBZpoE2kazUeiWOBKuQNczOEtPPbU</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>157639867903</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>com.thimratv.app</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>movia-c4ef0</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>movia-c4ef0.firebasestorage.app</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:157639867903:ios:63bd57e22b7c906450fbca</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Loading…
x
Reference in New Issue
Block a user