Music_Player3/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift
2024-09-11 18:21:34 +08:00

538 lines
25 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Macro.swift
// MusicPlayer
//
// Created by Mr.Zhou on 2024/3/25.
//
import UIKit
import Foundation
import AVFoundation
import AppTrackingTransparency
import AdSupport
import MessageUI
import MarqueeLabel
import UserNotifications
@_exported import JXSegmentedView
@_exported import JXPagingView
//JXPagingListContainerViewextensionJXSegmentedViewListContainer
extension JXPagingListContainerView: JXSegmentedViewListContainer {}
//MARK: -
///
let screen_Width = UIScreen.main.bounds.width
///
let screen_Height = UIScreen.main.bounds.height
///
let width = screen_Width / 375
///
let height = screen_Height / 667
///
#if __IPHONE_13_0
let statusBarHeight:CGFloat = UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.size.height
#else
let statusBarHeight:CGFloat = UIApplication.shared.statusBarFrame.size.height
#endif
///
let navAndstatusBarHeight = statusBarHeight + 50*width
///
let iphoneX = ((statusBarHeight != 20) ? true : false)
///
let LOCAL_RELEASE_VERSION = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
///
let App_Name = Bundle.main.infoDictionary!["CFBundleDisplayName"] as! String
///
let Phone_Model = UIDevice.current.model
///
let System_Version = UIDevice.current.systemVersion
///
var Language_first_local:String {
let first = Locale.preferredLanguages.first!
let languageCode = Locale(identifier: first).languageCode
if let code = languageCode {
return code
} else {
return "en"
}
}
///
var app_Version:String{
if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
return version
}else {
return "1.0.0"
}
}
///
let bottomPadding = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
///
let placeholderImage:UIImage = UIImage(named: "placeholder")!
///
let love_songBGImage:UIImage = UIImage(named: "Love Songs'bg")!
///
let love_artistBGImage:UIImage = UIImage(named: "Love Artists'bg")!
///线
let offline_songBGImage:UIImage = UIImage(named: "Offline Songs'bg")!
///
let privacyUrl:URL = .init(string: "https://musiclax.mystrikingly.com/privacy")!
///
let serviceUrl:URL = .init(string: "https://musiclax.mystrikingly.com/terms")!
///
let gradientTextColors:[CGColor] = [UIColor(red: 0, green: 0.863, blue: 1, alpha: 1).cgColor,
UIColor(red: 0, green: 1, blue: 0.561, alpha: 1).cgColor,
UIColor(red: 0.776, green: 1, blue: 0.639, alpha: 1).cgColor]
///-绿
let greenTextColor:UIColor = .init(hex: "#80F988", alpha: 1.0)
///
var isUpDateReminder:Bool = false{
willSet{
if newValue == true {
//
NotificationCenter.notificationKey.post(notificationName: .update_reminder)
}
}
}
//MARK: -
//
func coreDefaultValues() {
if UserDefaults.standard.string(forKey: "OpenICEID") != nil {
print("清理旧数据")
UserDefaults.standard.removeObject(forKey: "OpenICEID")
}
if UserDefaults.standard.object(forKey: "OpenICEID") == nil {
print("第一次启动添加广告ID")
if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/2126815630", ad: "AdMob", type: .Insert),
.init(level: 2, identifier: "ca-app-pub-1371732277241593/8500652294", ad: "AdMob", type: .Open),
.init(level: 1, identifier: "ca-app-pub-1371732277241593/4561407280", ad: "AdMob", type: .Insert),
.init(level: 0, identifier: "ca-app-pub-1371732277241593/1926543650", ad: "AdMob", type: .Open)]) {
//广ID
UserDefaults.standard.set(array, forKey: "OpenICEID")
}
}
if UserDefaults.standard.string(forKey: "OpenHOSTID") != nil {
UserDefaults.standard.removeObject(forKey: "OpenHOSTID")
}
if UserDefaults.standard.object(forKey: "OpenHOSTID") == nil {
if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/9262752398", ad: "AdMob", type: .Insert),
.init(level: 2, identifier: "ca-app-pub-1371732277241593/6536516707", ad: "AdMob", type: .Open),
.init(level: 1, identifier: "ca-app-pub-1371732277241593/9239018894", ad: "AdMob", type: .Insert),
.init(level: 0, identifier: "ca-app-pub-1371732277241593/3299335073", ad: "AdMob", type: .Open)]) {
//广ID
UserDefaults.standard.set(array, forKey: "OpenHOSTID")
}
}
if UserDefaults.standard.string(forKey: "SearchINSERTID") != nil {
UserDefaults.standard.removeObject(forKey: "SearchINSERTID")
}
if UserDefaults.standard.object(forKey: "SearchINSERTID") == nil {
if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/5323507386", ad: "AdMob", type: .Insert),
.init(level: 2, identifier: "ca-app-pub-1371732277241593/6877962328", ad: "AdMob", type: .Insert),
.init(level: 1, identifier: "ca-app-pub-1371732277241593/4251798981", ad: "AdMob", type: .Insert),
.init(level: 0, identifier: "ca-app-pub-1371732277241593/8622500865", ad: "AdMob", type: .Insert)]) {
//广ID
UserDefaults.standard.set(array, forKey: "SearchINSERTID")
}
}
if UserDefaults.standard.string(forKey: "SearchNATIVEID") != nil {
UserDefaults.standard.removeObject(forKey: "SearchNATIVEID")
}
if UserDefaults.standard.object(forKey: "SearchNATIVEID") == nil {
if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/5674216970", ad: "AdMob", type: .Native)]) {
//广ID
UserDefaults.standard.set(array, forKey: "SearchNATIVEID")
}
}
if UserDefaults.standard.string(forKey: "PlayerINSERTID") != nil {
UserDefaults.standard.removeObject(forKey: "PlayerINSERTID")
}
if UserDefaults.standard.object(forKey: "PlayerINSERTID") == nil {
if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/9569874154", ad: "AdMob", type: .Insert),
.init(level: 2, identifier: "ca-app-pub-1371732277241593/8256792481", ad: "AdMob", type: .Insert),
.init(level: 1, identifier: "ca-app-pub-1371732277241593/8031261896", ad: "AdMob", type: .Insert),
.init(level: 0, identifier: "ca-app-pub-1371732277241593/4182802216", ad: "AdMob", type: .Insert)]) {
//广ID
UserDefaults.standard.set(array, forKey: "PlayerINSERTID")
}
}
if UserDefaults.standard.string(forKey: "LibraryINSERTID") != nil {
UserDefaults.standard.removeObject(forKey: "LibraryINSERTID")
}
if UserDefaults.standard.object(forKey: "LibraryINSERTID") == nil {
if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/4607022200", ad: "AdMob", type: .Insert),
.init(level: 2, identifier: "ca-app-pub-1371732277241593/3104538158", ad: "AdMob", type: .Insert),
.init(level: 1, identifier: "ca-app-pub-1371732277241593/8931897131", ad: "AdMob", type: .Insert),
.init(level: 0, identifier: "ca-app-pub-1371732277241593/5298812459", ad: "AdMob", type: .Insert)]) {
//广ID
UserDefaults.standard.set(array, forKey: "LibraryINSERTID")
}
}
if UserDefaults.standard.string(forKey: "LibraryNATIVEID") != nil {
UserDefaults.standard.removeObject(forKey: "LibraryNATIVEID")
}
if UserDefaults.standard.object(forKey: "LibraryNATIVEID") == nil {
if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/4683255855", ad: "AdMob", type: .Native)]) {
//广ID
UserDefaults.standard.set(array, forKey: "LibraryNATIVEID")
}
}
//
if UserDefaults.standard.string(forKey: "ClientVersion") == nil {
UserDefaults.standard.set("1.20240618.01.00", forKey: "ClientVersion")
}
if UserDefaults.standard.string(forKey: "PlayerVersion") == nil {
UserDefaults.standard.set("6.18.1", forKey: "PlayerVersion")
}
if UserDefaults.standard.object(forKey: "NotificationBodyTexts") == nil {
UserDefaults.standard.set(["✅ Enjoy your favorite offline music.Your new playlist is ready! Enjoy your favorite offline music.",
"🕛 Now is the time to enjoy non-stop music!",
"🚀 Boost your day with new offline music selections!",
"🎵 Ready for a music adventure? Download latest tracks for offline fun!",
"❤️ Your favorite songs are available for offline playback now.",
"😍 New recommendations tailored for you. Add them to your library.",
"👉 Touch the music journey, start now",
"🔥 Summer hits ready for download. Enjoy offline!",
"🙌 Your music, your way. 💎💎💎",
"💡 Discover today's music,enjoy the moment!"
], forKey: "NotificationBodyTexts")
if UserDefaults.standard.object(forKey: "OpenAppDuration") == nil {
UserDefaults.standard.set(10, forKey: "OpenAppDuration")
}
if UserDefaults.standard.object(forKey: "InterstitialDuration") == nil {
UserDefaults.standard.set(40, forKey: "InterstitialDuration")
}
if UserDefaults.standard.object(forKey: "IntermediaryDuration") == nil {
UserDefaults.standard.set(40, forKey: "IntermediaryDuration")
}
}
}
///广Data
func coreAdModelforJson(_ array:[MPPositive_AdModelModel]) -> Data? {
guard array.isEmpty != true else {return nil}
do{
let jsonData = try JSONEncoder().encode(array)
return jsonData
}catch {
//
print("用户默认广告配置设置失败,失败原因:\(error.localizedDescription)")
return nil
}
}
///data广
func jsonforCoreAdModel(_ data:Data) -> [MPPositive_AdModelModel]? {
do{
let array:[MPPositive_AdModelModel] = try JSONDecoder().decode([MPPositive_AdModelModel].self, from: data)
return array
}catch{
//
print("用户默认广告配置设置失败,失败原因:\(error.localizedDescription)")
return nil
}
}
///SongsData
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
}
}
///DataSongs
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?
///A
var MPSideA_ModalType:MPSideA_PresentModal = .Timer
///B
var MPPositive_ModalType:MPPositive_PresentModal = .PlayerList
///nextIDID
func improveDataforLycirsAndRelated(_ song:MPPositive_SongItemModel, completion:@escaping(((String?,String?)) -> Void)) {
//next
MP_NetWorkManager.shared.requestNextLyricsAndRelated(song){ result in
completion(result)
}
}
///player
func improveDataforResouceAndCover(_ song:MPPositive_SongItemModel, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void)) {
//player
MP_NetWorkManager.shared.requestAndroidPlayer(song.videoId ?? "", playlistId: "", clickTrackingParams: song.clickTrackingParams ?? "") { resourceUrls, coverUrls in
completion(resourceUrls,coverUrls)
}
}
///
func setTimesToMinSeconds(_ time:TimeInterval) -> String {
//
let min = Int((time.isNaN ? 0:time) / 60)
let second = Int((time.isNaN ? 0:time).truncatingRemainder(dividingBy: 60))
return "\(min < 10 ? "0\(min)":"\(min)"):\(second < 10 ? "0\(second)":"\(second)")"
}
///
func setTimesToMins(_ time:TimeInterval) -> String {
//
let min = Int((time.isNaN ? 0:time) / 60)
return "\(min < 10 ? "0\(min)":"\(min)")"
}
///
func authorize(observe:UIViewController) -> Bool{
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.audio)
switch status {
case .authorized:
return true
case .notDetermined:
//
AVCaptureDevice.requestAccess(for: AVMediaType.audio, completionHandler: {(status) in
DispatchQueue.main.async(execute: {() -> Void in
_ = authorize(observe: observe)
})
})
default: ()
DispatchQueue.main.async(execute: { () -> Void in
let alertController = UIAlertController(title: "Get Microphone Access",message: "“HiMelody” asks you to turn on your microphone to recognize the decibels around you and turns on white noise for you automatically. Please go to the “Settings” page to turn on the microphone permission",preferredStyle: .alert)
let cancelAction = UIAlertAction(title:"Cancel", style: .cancel, handler:nil)
let settingsAction = UIAlertAction(title:"Settings", style: .default, handler: {
(action) -> Void in
let url = URL(string: UIApplication.openSettingsURLString)
if let url = url, UIApplication.shared.canOpenURL(url) {
if #available(iOS 10, *) {
UIApplication.shared.open(url, options: [:],
completionHandler: {
(success) in
})
} else {
UIApplication.shared.openURL(url)
}
}
})
alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
observe.present(alertController, animated: true)
})
}
return false
}
///Label
func createLabel(_ text:String? = nil, font:UIFont, textColor:UIColor, textAlignment:NSTextAlignment, lines:Int = 1) -> UILabel {
let label = UILabel()
label.text = text ?? "text"
label.font = font
label.textColor = textColor
label.textAlignment = textAlignment
label.numberOfLines = lines
return label
}
///label
func createMarQueeLabel(_ text:String? = nil, font:UIFont, textColor:UIColor) -> MarqueeLabel {
let label = MarqueeLabel(frame: .init(x: 0, y: 0, width: screen_Width, height: 30*width), duration: 10, fadeLength: 10)
label.animationCurve = .linear
label.text = text ?? "text"
label.font = font
label.textColor = textColor
label.numberOfLines = 1
label.type = .continuous
label.restartLabel()
return label
}
///
func switchPlayTypeBtnIcon(_ btn:UIButton) {
switch MP_PlayerManager.shared.getPlayType() {
case .normal://
btn.setBackgroundImage(UIImage(named: "Player_Normal'logo"), for: .normal)
case .random://
btn.setBackgroundImage(UIImage(named: "Player_Shuffle'logo"), for: .normal)
case .single://
btn.setBackgroundImage(UIImage(named: "Player_Single'logo"), for: .normal)
}
}
///广
func requestTrackingAuthorization(completion: @escaping (String?) -> Void) {
if #available(iOS 14, *) {
var attemptsLeft = 3
func requestAuth() {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
print("Authorized: IDFA = \(idfa)")
completion(idfa)
case .denied, .restricted:
print("Denied or Restricted")
completion(nil)
case .notDetermined:
print("Not Determined")
attemptsLeft -= 1
if attemptsLeft > 0 {
requestAuth() //
} else {
print("Reached maximum number of attempts")
completion(nil)
}
@unknown default:
print("Unknown status")
completion(nil)
}
}
}
requestAuth() //
} else {
if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
print("Tracking enabled: IDFA = \(idfa)")
completion(idfa)
} else {
print("Tracking not enabled")
completion(nil)
}
}
}
///\n\n
func truncateTextAfterTwoNewlines(from text: String) -> String {
//
let pattern = "\n{2,}.*"
let regex = try! NSRegularExpression(pattern: pattern, options: [.dotMatchesLineSeparators])
// 使
let truncatedText = regex.stringByReplacingMatches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count), withTemplate: "")
return truncatedText
}
///
func saveLoadVideoItem(_ song:MPPositive_SongItemModel?, completion:(() -> Void)?) {
MP_DownloadManager.shared.loadQueue.async {
guard let song = song?.copy() as? MPPositive_SongItemModel else {return}
MP_CoreDataHandlerManager.shared.context.perform {
//
let item = try? MPPositive_DownloadItemModel.create()
item?.coverImage = song.coverUrls?.last
item?.reviewImage = song.reviewUrls?.last
item?.title = song.title
item?.longBylineText = song.longBylineText
item?.lengthText = song.lengthText
item?.shortBylineText = song.shortBylineText
item?.lyrics = song.lyrics
item?.lyricsID = song.lyricsID
item?.videoId = song.videoId
item?.relatedID = song.relatedID
item?.addTime = Date()
item?.artistID = song.artistID
item?.albumID = song.albumID
item?.playListID = song.playListID
//
let recent = try? MPPositive_RecentlyModel.create()
recent?.coverImage = song.coverUrls?.last
recent?.reviewImage = song.reviewUrls?.last
recent?.title = song.title
recent?.subtitle = "\(song.longBylineText ?? "")\(song.shortBylineText ?? "")"
recent?.videoId = song.videoId
recent?.lyricsID = song.lyricsID
recent?.relatedID = song.relatedID
recent?.addTime = Date()
recent?.level = 3
recent?.artistID = song.artistID
recent?.albumID = song.albumID
recent?.playListID = song.playListID
//
MPPositive_DownloadItemModel.save()
completion?()
//
MPPositive_LoadCoreModel.shared.reloadLoadSongViewModel(nil)
MPPositive_LoadCoreModel.shared.reloadRecents(nil)
DispatchQueue.main.async {
//
MP_AnalyticsManager.shared.player_b_downloadsuccess_actionAction(item?.videoId ?? "", videoname: item?.title ?? "", artistname: item?.shortBylineText ?? "")
print("完成了对\(song.title ?? "")的下载数据保存")
}
}
}
}
///
func scheduleDailyNotifications() {
UNUserNotificationCenter.current().getNotificationSettings {
settings in
switch settings.authorizationStatus {
case .authorized:
DispatchQueue.main.async {
guard let texts = UserDefaults.standard.object(forKey: "NotificationBodyTexts") as? [String], texts.isEmpty != true else {return}
//
let center = UNUserNotificationCenter.current()
//body
let firstContent = UNMutableNotificationContent()
firstContent.title = ""
firstContent.body = texts.randomElement() ?? ""
firstContent.sound = UNNotificationSound.default
//-10
var firstDateComponents = DateComponents()
firstDateComponents.hour = 10
let firstTrigger = UNCalendarNotificationTrigger(dateMatching: firstDateComponents, repeats: true)
//body
let secondContent = UNMutableNotificationContent()
secondContent.title = ""
secondContent.body = texts.randomElement() ?? ""
secondContent.sound = UNNotificationSound.default
//-2
var secondDateComponents = DateComponents()
secondDateComponents.hour = 14
let secondTrigger = UNCalendarNotificationTrigger(dateMatching: secondDateComponents, repeats: true)
//
let firstRequest = UNNotificationRequest(identifier: "relax.offline.mp3.morningNotification", content: firstContent, trigger: firstTrigger)
let secondRequest = UNNotificationRequest(identifier: "relax.offline.mp3.afternoonNotification", content: secondContent, trigger: secondTrigger)
//
center.add(firstRequest) { error in
if let error = error {
print("更新上午通知失败,失败原因: \(error)")
}
}
center.add(secondRequest) { error in
if let error = error {
print("更新下午通知失败,失败原因: \(error)")
}
}
}
default:
break
}
}
}
func printCallStack() {
let callStack = Thread.callStackSymbols
print("Call Stack: \(callStack)")
}
///
func postUpdateReminder(_ observe:UIViewController) {
let alter = UIAlertController(title: "Update available".localizableString(), message: "A new version of our app is now available! We've made some exciting improvements and added new features to enhance your experience. To enjoy these updates and continue using our app seamlessly, please update to the latest version now.\nTap on 'Update' to get the latest features and enhancements.".localizableString(), preferredStyle: .alert)
//
let not = UIAlertAction(title: "Not now".localizableString(), style: .cancel) { action in
//
MP_AnalyticsManager.shared.update_reminder_cancelAction()
print("用户取消更新")
}
alter.addAction(not)
let updata = UIAlertAction(title: "Update".localizableString(), style: .destructive) { action in
//
MP_AnalyticsManager.shared.update_reminder_sureAction()
//AppStore
if let url = URL(string: "https://apps.apple.com/app/6502973957") {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
alter.addAction(updata)
MP_AnalyticsManager.shared.update_reminder_showAction()
observe.present(alter, animated: true)
}