b面1.1.2上次播放实现
This commit is contained in:
parent
d3d3da4f6e
commit
abd0c979de
@ -1703,7 +1703,7 @@
|
|||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1.1.1.1;
|
CURRENT_PROJECT_VERSION = 1.1.2.1;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEVELOPMENT_TEAM = T93S37G27F;
|
DEVELOPMENT_TEAM = T93S37G27F;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@ -1723,7 +1723,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.1.1;
|
MARKETING_VERSION = 1.1.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
|
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -1746,7 +1746,7 @@
|
|||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1.1.1.1;
|
CURRENT_PROJECT_VERSION = 1.1.2.1;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEVELOPMENT_TEAM = T93S37G27F;
|
DEVELOPMENT_TEAM = T93S37G27F;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@ -1766,7 +1766,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.1.1;
|
MARKETING_VERSION = 1.1.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
|
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@ -60,6 +60,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
switch_lunch()
|
switch_lunch()
|
||||||
//执行用户启动事件日志
|
//执行用户启动事件日志
|
||||||
MP_AnalyticsManager.shared.user_launchAction()
|
MP_AnalyticsManager.shared.user_launchAction()
|
||||||
|
// NotificationCenter.default.addObserver(self, selector: #selector(appWillTerminateAction(_ :)), name:UIApplication.willTerminateNotification, object: nil)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool {
|
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool {
|
||||||
@ -190,6 +191,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
print("返回前台")
|
print("返回前台")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//MARK: - 当应用被用户关闭时
|
||||||
|
func applicationWillTerminate(_ application: UIApplication) {
|
||||||
|
print("应用关闭了")
|
||||||
|
//检索应用是否播放歌曲
|
||||||
|
guard let load = MP_PlayerManager.shared.loadPlayer, let videoId = load.currentVideoId, let songs = load.songVideos else {return}
|
||||||
|
//将songs转为数据
|
||||||
|
guard let data = coreSongsforJson(songs) else {return}
|
||||||
|
//当前音乐情况是否合理加载了数据
|
||||||
|
let last:[String:Any] = ["currentVideoId":videoId,
|
||||||
|
"Songs":data]
|
||||||
|
UserDefaults.standard.set(last, forKey: "Last_Play_Songs")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Core Data stack
|
// MARK: - Core Data stack
|
||||||
lazy var persistentContainer: NSPersistentContainer = {
|
lazy var persistentContainer: NSPersistentContainer = {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -198,8 +198,29 @@ func jsonforCoreAdModel(_ data:Data) -> [MPPositive_AdModelModel]? {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
///将Songs模型组转为Data
|
||||||
|
func coreSongsforJson(_ array:[MPPositive_SongItemModel]) -> Data? {
|
||||||
|
guard array.isEmpty != true else {return nil}
|
||||||
|
do{
|
||||||
|
let jsonData = try JSONEncoder().encode(array)
|
||||||
|
return jsonData
|
||||||
|
}catch {
|
||||||
|
//编译失败
|
||||||
|
print("歌曲模型组转为数据失败,失败原因:\(error.localizedDescription)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///将Data重新转化为Songs模型组
|
||||||
|
func jsonforCoreSongs(_ data:Data) ->[MPPositive_SongItemModel]? {
|
||||||
|
do{
|
||||||
|
let array:[MPPositive_SongItemModel] = try JSONDecoder().decode([MPPositive_SongItemModel].self, from: data)
|
||||||
|
return array
|
||||||
|
}catch{
|
||||||
|
//编译失败
|
||||||
|
print("数据转化Songs失败,失败原因:\(error.localizedDescription)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
///总事件闭包
|
///总事件闭包
|
||||||
typealias ActionBlock = () -> Void?
|
typealias ActionBlock = () -> Void?
|
||||||
///A面全局模态弹出类型
|
///A面全局模态弹出类型
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class MP_AdMobManager: NSObject, GADFullScreenContentDelegate, GADNativeAdLoader
|
|||||||
static let shared = MP_AdMobManager()
|
static let shared = MP_AdMobManager()
|
||||||
private let sharedInstance = GADMobileAds.sharedInstance()
|
private let sharedInstance = GADMobileAds.sharedInstance()
|
||||||
///广告总开关
|
///广告总开关
|
||||||
private var openAdStatus:Bool = true
|
private var openAdStatus:Bool = false
|
||||||
///广告过期时间(50分钟)
|
///广告过期时间(50分钟)
|
||||||
private let expirationTime:TimeInterval = 3000
|
private let expirationTime:TimeInterval = 3000
|
||||||
|
|
||||||
|
|||||||
@ -68,11 +68,11 @@ class MP_NetWorkManager: NSObject {
|
|||||||
private var playerVersion:String!
|
private var playerVersion:String!
|
||||||
///禁止接入IP信息组
|
///禁止接入IP信息组
|
||||||
private let banIPs:[String] = [
|
private let banIPs:[String] = [
|
||||||
"CN",
|
// "CN",
|
||||||
"HK",
|
// "HK",
|
||||||
"TW",
|
// "TW",
|
||||||
"JP",
|
// "JP",
|
||||||
"KR"
|
// "KR"
|
||||||
]
|
]
|
||||||
///允许访问的区域Code(对部分内容进行塞选)
|
///允许访问的区域Code(对部分内容进行塞选)
|
||||||
private let codes:[String] = [
|
private let codes:[String] = [
|
||||||
|
|||||||
@ -118,6 +118,12 @@ class MP_PlayerManager:NSObject{
|
|||||||
}
|
}
|
||||||
//当前音乐的字典
|
//当前音乐的字典
|
||||||
private var currentInfo:[String:Any]?
|
private var currentInfo:[String:Any]?
|
||||||
|
//是否展示最后一首状态
|
||||||
|
private var isLast:Bool = false
|
||||||
|
//设置是否页面展示最后一首状态
|
||||||
|
func setLastStatus(bool:Bool) {
|
||||||
|
isLast = bool
|
||||||
|
}
|
||||||
//当前播放器状态
|
//当前播放器状态
|
||||||
private var playState:MP_PlayerStateType = .Null{
|
private var playState:MP_PlayerStateType = .Null{
|
||||||
didSet{
|
didSet{
|
||||||
@ -354,6 +360,11 @@ class MP_PlayerManager:NSObject{
|
|||||||
if startActionBlock != nil {
|
if startActionBlock != nil {
|
||||||
startActionBlock!()
|
startActionBlock!()
|
||||||
}
|
}
|
||||||
|
//当前是否上次播放展示状态,是的话,手动暂停
|
||||||
|
if isLast {
|
||||||
|
pause()
|
||||||
|
isLast = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
//没有足够的数据支持播放
|
//没有足够的数据支持播放
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
///歌曲模型(音乐与视频)(当网络拉取内容确定为歌曲时,转为该模型)
|
///歌曲模型(音乐与视频)(当网络拉取内容确定为歌曲时,转为该模型)
|
||||||
class MPPositive_SongItemModel: NSObject {
|
class MPPositive_SongItemModel: NSObject, Codable {
|
||||||
///序列号(在当前列表中的排序)
|
///序列号(在当前列表中的排序)
|
||||||
var index:Int!
|
var index:Int!
|
||||||
///视频源路径组(等级制,默认取第一条最低质量)
|
///视频源路径组(等级制,默认取第一条最低质量)
|
||||||
|
|||||||
@ -28,6 +28,8 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//当前播放音乐
|
||||||
|
var currentVideoId:String?
|
||||||
//监听器
|
//监听器
|
||||||
private var itemObservation: NSKeyValueObservation?
|
private var itemObservation: NSKeyValueObservation?
|
||||||
// private var loadQueue:DispatchQueue!
|
// private var loadQueue:DispatchQueue!
|
||||||
@ -45,7 +47,7 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
|||||||
//根据列表生成一份随机播放列表
|
//根据列表生成一份随机播放列表
|
||||||
self.randomVideos = self.songVideos.shuffled()
|
self.randomVideos = self.songVideos.shuffled()
|
||||||
self.listViewVideos = []
|
self.listViewVideos = []
|
||||||
|
self.currentVideoId = currentVideoId
|
||||||
}
|
}
|
||||||
//启动对于当前音乐的监听器
|
//启动对于当前音乐的监听器
|
||||||
private func startObservingCurrentVideoItem() {
|
private func startObservingCurrentVideoItem() {
|
||||||
@ -83,6 +85,8 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
|||||||
|
|
||||||
///将选中Video的上1位,下两位项包括本身总计4项Video进行补全转为ViewModel,并播放这首音乐
|
///将选中Video的上1位,下两位项包括本身总计4项Video进行补全转为ViewModel,并播放这首音乐
|
||||||
func improveData(_ targetVideoId:String, isRandom:Bool = false) {
|
func improveData(_ targetVideoId:String, isRandom:Bool = false) {
|
||||||
|
//更新当前播放音乐ID
|
||||||
|
self.currentVideoId = targetVideoId
|
||||||
//对于选中Video的集合
|
//对于选中Video的集合
|
||||||
var array:[MPPositive_SongItemModel] = []
|
var array:[MPPositive_SongItemModel] = []
|
||||||
if isRandom {
|
if isRandom {
|
||||||
|
|||||||
@ -82,6 +82,17 @@ class MPPositive_HomeViewController: MPPositive_BaseViewController, UIViewContro
|
|||||||
MPPositive_BrowseLoadViewModel.shared.reloadBrowseLists()
|
MPPositive_BrowseLoadViewModel.shared.reloadBrowseLists()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//当home展示后尝试获取最后一次播放歌曲内容
|
||||||
|
guard let last = UserDefaults.standard.object(forKey: "Last_Play_Songs") as? [String:Any] else {return}
|
||||||
|
guard let currentVideoId = last["currentVideoId"] as? String, let data = last["Songs"] as? Data, let array = jsonforCoreSongs(data) else {return}
|
||||||
|
//数据获取完成,使用这些数据合成一个Load
|
||||||
|
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideoId)
|
||||||
|
lodaViewModel.improveData(currentVideoId)
|
||||||
|
//更改播放器播放类型
|
||||||
|
MP_PlayerManager.shared.setPlayType(.normal)
|
||||||
|
MP_PlayerManager.shared.setLastStatus(bool: true)
|
||||||
|
MP_PlayerManager.shared.loadPlayer = lodaViewModel
|
||||||
|
|
||||||
}
|
}
|
||||||
deinit {
|
deinit {
|
||||||
NotificationCenter.default.removeObserver(self)
|
NotificationCenter.default.removeObserver(self)
|
||||||
|
|||||||
@ -68,6 +68,11 @@ class MPPositive_SearchViewController: MPPositive_BaseViewController {
|
|||||||
[weak self] in
|
[weak self] in
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
historyCollectionView.reloadData()
|
historyCollectionView.reloadData()
|
||||||
|
historyCollectionView.layoutIfNeeded()
|
||||||
|
guard let layout = historyCollectionView.collectionViewLayout as? MPPositive_TagFlowLayout, let height = layout.layoutAttributeds.last?.frame.maxY else {return}
|
||||||
|
historyCollectionView.snp.updateConstraints { make in
|
||||||
|
make.height.equalTo(height)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
grideCollectionView.reloadData()
|
grideCollectionView.reloadData()
|
||||||
}
|
}
|
||||||
@ -107,7 +112,7 @@ class MPPositive_SearchViewController: MPPositive_BaseViewController {
|
|||||||
historyCollectionView.snp.makeConstraints { make in
|
historyCollectionView.snp.makeConstraints { make in
|
||||||
make.left.right.equalToSuperview()
|
make.left.right.equalToSuperview()
|
||||||
make.top.equalTo(deleteBtn.snp.bottom).offset(6*width)
|
make.top.equalTo(deleteBtn.snp.bottom).offset(6*width)
|
||||||
make.height.equalTo(130*width)
|
make.height.equalTo(30*width)
|
||||||
}
|
}
|
||||||
view.addSubview(grideCollectionView)
|
view.addSubview(grideCollectionView)
|
||||||
grideCollectionView.snp.makeConstraints { make in
|
grideCollectionView.snp.makeConstraints { make in
|
||||||
@ -159,10 +164,18 @@ class MPPositive_SearchViewController: MPPositive_BaseViewController {
|
|||||||
MPPositive_SearchTagModel.fetchAll { [weak self] items in
|
MPPositive_SearchTagModel.fetchAll { [weak self] items in
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
items.forEach({(MPPositive_SearchTagModel.delete($0))})
|
items.forEach({(MPPositive_SearchTagModel.delete($0))})
|
||||||
|
guard let layout = historyCollectionView.collectionViewLayout as? MPPositive_TagFlowLayout else {return}
|
||||||
|
layout.originxArray.removeAll()
|
||||||
|
layout.originyArray.removeAll()
|
||||||
|
layout.layoutAttributeds.removeAll()
|
||||||
MPPositive_LoadCoreModel.shared.reloadSearchTags {
|
MPPositive_LoadCoreModel.shared.reloadSearchTags {
|
||||||
[weak self] in
|
[weak self] in
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
historyCollectionView.reloadData()
|
historyCollectionView.reloadData()
|
||||||
|
historyCollectionView.layoutIfNeeded()
|
||||||
|
historyCollectionView.snp.updateConstraints { make in
|
||||||
|
make.height.equalTo(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,6 +237,8 @@ class MPPositive_TagFlowLayout: UICollectionViewFlowLayout {
|
|||||||
var originxArray:[CGFloat]!
|
var originxArray:[CGFloat]!
|
||||||
//y值数组
|
//y值数组
|
||||||
var originyArray:[CGFloat]!
|
var originyArray:[CGFloat]!
|
||||||
|
//记录的布局值
|
||||||
|
var layoutAttributeds:[UICollectionViewLayoutAttributes] = []
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
//列间距
|
//列间距
|
||||||
@ -257,6 +272,7 @@ class MPPositive_TagFlowLayout: UICollectionViewFlowLayout {
|
|||||||
let theAttrs = layoutAttributesForItem(at: attrs.indexPath)
|
let theAttrs = layoutAttributesForItem(at: attrs.indexPath)
|
||||||
mutArray.append(theAttrs!)
|
mutArray.append(theAttrs!)
|
||||||
})
|
})
|
||||||
|
layoutAttributeds = mutArray
|
||||||
return mutArray
|
return mutArray
|
||||||
}
|
}
|
||||||
//处理单个item的layoutAttributes
|
//处理单个item的layoutAttributes
|
||||||
|
|||||||
@ -125,8 +125,8 @@ class MPPositive_SearchResultPreviewShowView: UIView, JXSegmentedListContainerVi
|
|||||||
//MARK: - tableView
|
//MARK: - tableView
|
||||||
extension MPPositive_SearchResultPreviewShowView:UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate {
|
extension MPPositive_SearchResultPreviewShowView:UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate {
|
||||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||||
if scrollBlock != nil {
|
if let block = scrollBlock {
|
||||||
scrollBlock!()
|
block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func numberOfSections(in tableView: UITableView) -> Int {
|
func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user