1.2.1离线模式优化,AppLovin广告配置添加
This commit is contained in:
parent
864f19ca7a
commit
0c4a1df6dd
2
Podfile
2
Podfile
@ -29,6 +29,8 @@ pod "DownloadButton"
|
||||
pod 'Tiercel'
|
||||
#文本跑马灯
|
||||
pod 'MarqueeLabel'
|
||||
|
||||
|
||||
#广告组
|
||||
pod 'GoogleUserMessagingPlatform', '2.4.0'
|
||||
pod 'Google-Mobile-Ads-SDK', '11.4.0'
|
||||
|
||||
@ -179,6 +179,6 @@ SPEC CHECKSUMS:
|
||||
Tiercel: c0a73f876a72800333b15f4e7e48791f4ad21e90
|
||||
VungleAds: 4823f53e691ba140ff21e3a3a6897af789832a36
|
||||
|
||||
PODFILE CHECKSUM: 6a95ca6014572e024266fe6dd05d870b42d7be49
|
||||
PODFILE CHECKSUM: 5af34d4e7dc09fde7b668a4368b6fc382756eebd
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
2
Pods/Manifest.lock
generated
2
Pods/Manifest.lock
generated
@ -179,6 +179,6 @@ SPEC CHECKSUMS:
|
||||
Tiercel: c0a73f876a72800333b15f4e7e48791f4ad21e90
|
||||
VungleAds: 4823f53e691ba140ff21e3a3a6897af789832a36
|
||||
|
||||
PODFILE CHECKSUM: 6a95ca6014572e024266fe6dd05d870b42d7be49
|
||||
PODFILE CHECKSUM: 5af34d4e7dc09fde7b668a4368b6fc382756eebd
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
CB0B368D2C65AEEF004036E2 /* Wave_Animation.json in Resources */ = {isa = PBXBuildFile; fileRef = CB0B368C2C65AEEF004036E2 /* Wave_Animation.json */; };
|
||||
CB0B368F2C65B026004036E2 /* MP_WaveAnimationMaskView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0B368E2C65B026004036E2 /* MP_WaveAnimationMaskView.swift */; };
|
||||
CB0B36912C65EBFC004036E2 /* MPPositive_BaseShowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0B36902C65EBFC004036E2 /* MPPositive_BaseShowView.swift */; };
|
||||
CB0D07BB2C9AACD2005B9768 /* MP_AppLovinManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0D07BA2C9AACD2005B9768 /* MP_AppLovinManager.swift */; };
|
||||
CB0D33972C7EF73700C85816 /* MPPositive_PersonalListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0D33962C7EF73700C85816 /* MPPositive_PersonalListViewModel.swift */; };
|
||||
CB0D339B2C7F2AAC00C85816 /* MPPositive_PersonalisedRecommendationsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0D339A2C7F2AAC00C85816 /* MPPositive_PersonalisedRecommendationsTableViewCell.swift */; };
|
||||
CB108C872C901A5E0017C40F /* MP_LuxServerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB108C862C901A5E0017C40F /* MP_LuxServerManager.swift */; };
|
||||
@ -32,6 +33,7 @@
|
||||
CB20A0702C53BDBF00FC5AFC /* MP_WebVisitorDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB20A06F2C53BDBF00FC5AFC /* MP_WebVisitorDataManager.swift */; };
|
||||
CB2CAAD42C59DC1100EF691D /* MPPositive_TrashListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB2CAAD32C59DC1100EF691D /* MPPositive_TrashListModel.swift */; };
|
||||
CB2CAAD82C5A1AC500EF691D /* MP_IAPViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB2CAAD52C5A1AC500EF691D /* MP_IAPViewController.swift */; };
|
||||
CB51340E2C9C1E4800833AD5 /* MP_ADSimpleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB51340D2C9C1E4800833AD5 /* MP_ADSimpleManager.swift */; };
|
||||
CB6EEB8E2C5DFE6100AEC414 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB6EEB8D2C5DFE6100AEC414 /* StoreKit.framework */; };
|
||||
CB7FC5422C2AA01F00292A43 /* FacebookAEM in Frameworks */ = {isa = PBXBuildFile; productRef = CB7FC5412C2AA01F00292A43 /* FacebookAEM */; };
|
||||
CB7FC5442C2AA01F00292A43 /* FacebookBasics in Frameworks */ = {isa = PBXBuildFile; productRef = CB7FC5432C2AA01F00292A43 /* FacebookBasics */; };
|
||||
@ -250,7 +252,7 @@
|
||||
CBC2D6F82BFDF3D800E17703 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CBC2D6F72BFDF3D800E17703 /* Assets.xcassets */; };
|
||||
CBC2D6FB2BFDF3D800E17703 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = CBC2D6FA2BFDF3D800E17703 /* Base */; };
|
||||
CBC2D7D42BFDF4B900E17703 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = CBC2D7792BFDF4B900E17703 /* PrivacyInfo.xcprivacy */; };
|
||||
CBC3F2B22C3E76160075DC74 /* MPPositive_AdModelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC3F2B12C3E76160075DC74 /* MPPositive_AdModelModel.swift */; };
|
||||
CBC3F2B22C3E76160075DC74 /* MPPositive_AdItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC3F2B12C3E76160075DC74 /* MPPositive_AdItemModel.swift */; };
|
||||
CBC5E51D2C7D82A200336746 /* MPPositive_RecentlyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC5E51C2C7D82A200336746 /* MPPositive_RecentlyModel.swift */; };
|
||||
CBC5E51F2C7DAB8600336746 /* MPPositive_RecentlyViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC5E51E2C7DAB8600336746 /* MPPositive_RecentlyViewModel.swift */; };
|
||||
CBC81FBA2C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC81FB92C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift */; };
|
||||
@ -269,6 +271,7 @@
|
||||
CBDBDDF62C40FFC600767F0B /* MPPositive_GrideMoodViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBDBDDF52C40FFC600767F0B /* MPPositive_GrideMoodViewController.swift */; };
|
||||
CBDC4A292C61B88300960649 /* relax.offline.mp3.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = CBDC4A272C61B88300960649 /* relax.offline.mp3.xcdatamodeld */; };
|
||||
CBF3AEDA2C255B1200947AFC /* MPPositive_PlayListsShowTypeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF3AED92C255B1200947AFC /* MPPositive_PlayListsShowTypeView.swift */; };
|
||||
CBF769992C95678A00EF9B45 /* Devices.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF769982C95678A00EF9B45 /* Devices.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -298,6 +301,7 @@
|
||||
CB0B368C2C65AEEF004036E2 /* Wave_Animation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Wave_Animation.json; sourceTree = "<group>"; };
|
||||
CB0B368E2C65B026004036E2 /* MP_WaveAnimationMaskView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_WaveAnimationMaskView.swift; sourceTree = "<group>"; };
|
||||
CB0B36902C65EBFC004036E2 /* MPPositive_BaseShowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_BaseShowView.swift; sourceTree = "<group>"; };
|
||||
CB0D07BA2C9AACD2005B9768 /* MP_AppLovinManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_AppLovinManager.swift; sourceTree = "<group>"; };
|
||||
CB0D33962C7EF73700C85816 /* MPPositive_PersonalListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_PersonalListViewModel.swift; sourceTree = "<group>"; };
|
||||
CB0D339A2C7F2AAC00C85816 /* MPPositive_PersonalisedRecommendationsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_PersonalisedRecommendationsTableViewCell.swift; sourceTree = "<group>"; };
|
||||
CB108C862C901A5E0017C40F /* MP_LuxServerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_LuxServerManager.swift; sourceTree = "<group>"; };
|
||||
@ -308,6 +312,7 @@
|
||||
CB20A06F2C53BDBF00FC5AFC /* MP_WebVisitorDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_WebVisitorDataManager.swift; sourceTree = "<group>"; };
|
||||
CB2CAAD32C59DC1100EF691D /* MPPositive_TrashListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_TrashListModel.swift; sourceTree = "<group>"; };
|
||||
CB2CAAD52C5A1AC500EF691D /* MP_IAPViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_IAPViewController.swift; sourceTree = "<group>"; };
|
||||
CB51340D2C9C1E4800833AD5 /* MP_ADSimpleManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_ADSimpleManager.swift; sourceTree = "<group>"; };
|
||||
CB6EEB8D2C5DFE6100AEC414 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
CB7FC5472C2AC25C00292A43 /* MPPositive_CenterListSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_CenterListSearchView.swift; sourceTree = "<group>"; };
|
||||
CBAFC9F22C0A10500054500E /* MP_BaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MP_BaseViewController.swift; sourceTree = "<group>"; };
|
||||
@ -543,7 +548,7 @@
|
||||
CBC2D6FA2BFDF3D800E17703 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
CBC2D6FC2BFDF3D800E17703 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CBC2D7792BFDF4B900E17703 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
CBC3F2B12C3E76160075DC74 /* MPPositive_AdModelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_AdModelModel.swift; sourceTree = "<group>"; };
|
||||
CBC3F2B12C3E76160075DC74 /* MPPositive_AdItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_AdItemModel.swift; sourceTree = "<group>"; };
|
||||
CBC5E51C2C7D82A200336746 /* MPPositive_RecentlyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_RecentlyModel.swift; sourceTree = "<group>"; };
|
||||
CBC5E51E2C7DAB8600336746 /* MPPositive_RecentlyViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_RecentlyViewModel.swift; sourceTree = "<group>"; };
|
||||
CBC81FB92C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_HomeSinglesTableViewCell.swift; sourceTree = "<group>"; };
|
||||
@ -562,6 +567,7 @@
|
||||
CBDBDDF52C40FFC600767F0B /* MPPositive_GrideMoodViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_GrideMoodViewController.swift; sourceTree = "<group>"; };
|
||||
CBDC4A282C61B88300960649 /* MusicPlayer.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MusicPlayer.xcdatamodel; sourceTree = "<group>"; };
|
||||
CBF3AED92C255B1200947AFC /* MPPositive_PlayListsShowTypeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_PlayListsShowTypeView.swift; sourceTree = "<group>"; };
|
||||
CBF769982C95678A00EF9B45 /* Devices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Devices.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -679,6 +685,7 @@
|
||||
CBAFCA012C0A10500054500E /* Notification.swift */,
|
||||
CBAFCA032C0A10500054500E /* TableView.swift */,
|
||||
CBB75FDC2C4F7AA60041665D /* UIImageView.swift */,
|
||||
CBF769982C95678A00EF9B45 /* Devices.swift */,
|
||||
);
|
||||
path = "Extension(扩展)";
|
||||
sourceTree = "<group>";
|
||||
@ -757,7 +764,9 @@
|
||||
CBAFCA282C0A10500054500E /* MP_PlayerManager.swift */,
|
||||
CBAFCA202C0A10500054500E /* MP_AVURLAsset.swift */,
|
||||
CBAFCA1F2C0A10500054500E /* MP_AnalyticsManager.swift */,
|
||||
CB51340D2C9C1E4800833AD5 /* MP_ADSimpleManager.swift */,
|
||||
CBB6372B2C1C17C300F1DEC9 /* MP_AdMobManager.swift */,
|
||||
CB0D07BA2C9AACD2005B9768 /* MP_AppLovinManager.swift */,
|
||||
CBAFCA212C0A10500054500E /* MP_CacheManager.swift */,
|
||||
CBAFCA232C0A10500054500E /* MP_CoreDataHandlerManager.swift */,
|
||||
CBAFCA242C0A10500054500E /* MP_DownloadManager.swift */,
|
||||
@ -815,7 +824,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CBAFCA3D2C0A10500054500E /* MPPositive_ArtistHeaderModel.swift */,
|
||||
CBC3F2B12C3E76160075DC74 /* MPPositive_AdModelModel.swift */,
|
||||
CBC3F2B12C3E76160075DC74 /* MPPositive_AdItemModel.swift */,
|
||||
CBAFCA3E2C0A10500054500E /* MPPositive_BrowseItemModel.swift */,
|
||||
CBC5E51C2C7D82A200336746 /* MPPositive_RecentlyModel.swift */,
|
||||
CBC1FB792C50999800AC0633 /* MPPositive_LibraryItemModel.swift */,
|
||||
@ -969,8 +978,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CBAFCA792C0A10500054500E /* MPPositive_CustomTabBar.swift */,
|
||||
CBAFCA7A2C0A10500054500E /* MPPositive_CustomTabBarItem.swift */,
|
||||
CBAFCA7B2C0A10500054500E /* MPPositive_CustomTabBarView.swift */,
|
||||
CBAFCA7A2C0A10500054500E /* MPPositive_CustomTabBarItem.swift */,
|
||||
CBAFCA782C0A10500054500E /* MPPositive_BottomShowView.swift */,
|
||||
CBAFCA7C2C0A10500054500E /* MPPositive_MoreOperationDownLoadTableViewCell.swift */,
|
||||
CB0033F52C295E3100B18FD3 /* MPPositive_MoreOperationShowTableViewCell.swift */,
|
||||
@ -1637,7 +1646,7 @@
|
||||
CBAFCB442C0A10500054500E /* MPPositive_PresentationController.swift in Sources */,
|
||||
CB0968752C2121410045E55B /* GADTSmallTemplateView.m in Sources */,
|
||||
CBAFCB9B2C0A10500054500E /* MPSideA_CenterTableViewCell.swift in Sources */,
|
||||
CBC3F2B22C3E76160075DC74 /* MPPositive_AdModelModel.swift in Sources */,
|
||||
CBC3F2B22C3E76160075DC74 /* MPPositive_AdItemModel.swift in Sources */,
|
||||
CBAFCB412C0A10500054500E /* MPPositive_BaseViewController.swift in Sources */,
|
||||
CBCBA7D92C6DFD93004E5BEF /* MPPositive_SortTypeViewController.swift in Sources */,
|
||||
CBAFCB4E2C0A10500054500E /* MPPositive_PlayerListShowViewController.swift in Sources */,
|
||||
@ -1685,17 +1694,20 @@
|
||||
CBC1FB802C50E59C00AC0633 /* MPPositive_HomeLibraryListstableViewCell.swift in Sources */,
|
||||
CBAFCB792C0A10500054500E /* MPSideA_AddViewController.swift in Sources */,
|
||||
CBAFCB5A2C0A10500054500E /* MPPositive_ArtistDescriptionTableViewCell.swift in Sources */,
|
||||
CB51340E2C9C1E4800833AD5 /* MP_ADSimpleManager.swift in Sources */,
|
||||
CBAFCB272C0A10500054500E /* MPPositive_CollectionSongModel.swift in Sources */,
|
||||
CBAFCB562C0A10500054500E /* MPPositive_CustomTabBarView.swift in Sources */,
|
||||
CBAFCB6C2C0A10500054500E /* MPPositive_PlayerSilder.swift in Sources */,
|
||||
CBAFCB332C0A10500054500E /* MPPositive_CollectionSongViewModel.swift in Sources */,
|
||||
CBAFCB762C0A10500054500E /* MPSideA_LoadDataMusic.swift in Sources */,
|
||||
CBAFCB172C0A10500054500E /* MPPositive_JsonArtist.swift in Sources */,
|
||||
CBF769992C95678A00EF9B45 /* Devices.swift in Sources */,
|
||||
CBAFCB1A2C0A10500054500E /* MPPositive_JsonListAlbum.swift in Sources */,
|
||||
CBAFCB1F2C0A10500054500E /* MPPositive_JsonSearchResults.swift in Sources */,
|
||||
CBAFCB362C0A10500054500E /* MPPositive_ListHeaderViewModel.swift in Sources */,
|
||||
CBAFCB0F2C0A10500054500E /* MP_LocationManager.swift in Sources */,
|
||||
CBAFCB5E2C0A10500054500E /* MPPositive_ArtistShowListCollectionViewCell.swift in Sources */,
|
||||
CB0D07BB2C9AACD2005B9768 /* MP_AppLovinManager.swift in Sources */,
|
||||
CBAFCB6D2C0A10500054500E /* MPPositive_RecommendMemberCollectionViewCell.swift in Sources */,
|
||||
CB0D339B2C7F2AAC00C85816 /* MPPositive_PersonalisedRecommendationsTableViewCell.swift in Sources */,
|
||||
CBAFCB2B2C0A10500054500E /* MPPositive_SearchTagModel.swift in Sources */,
|
||||
@ -1899,7 +1911,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 1.2.0.1;
|
||||
CURRENT_PROJECT_VERSION = 1.2.1.1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = RAQJ4FNZUH;
|
||||
@ -1920,11 +1932,11 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.0;
|
||||
MARKETING_VERSION = 1.2.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Musiclax_Development;
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Musiclax_15ProDevelopment;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
@ -1945,7 +1957,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 1.2.0.1;
|
||||
CURRENT_PROJECT_VERSION = 1.2.1.1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = RAQJ4FNZUH;
|
||||
@ -1966,11 +1978,11 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.0;
|
||||
MARKETING_VERSION = 1.2.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Musiclax_Development;
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Musiclax_15ProDevelopment;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
|
||||
Binary file not shown.
@ -16,6 +16,7 @@ import FacebookCore
|
||||
import StoreKit
|
||||
import UserMessagingPlatform
|
||||
|
||||
|
||||
@_exported import IQKeyboardManagerSwift
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@ -47,8 +48,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
ActiveDaysCalculation()
|
||||
//FireBase初始化
|
||||
FirebaseApp.configure()
|
||||
//广告初始化
|
||||
MP_AdMobManager.shared.start()
|
||||
//AdMob广告初始化
|
||||
MP_ADSimpleManager.shared.start()
|
||||
//启动前销毁所有的下载任务
|
||||
MP_DownloadManager.shared.cancelAllTasksIfNeeded()
|
||||
setAudioSupport()
|
||||
@ -195,9 +196,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
//算出与后台时间节点的差值
|
||||
let duration = currentDate.timeIntervalSince(backDate)
|
||||
//获取插页间隔时长
|
||||
let times = MP_AdMobManager.shared.getOpenAppDuration()
|
||||
let times = MP_ADSimpleManager.shared.platform ? MP_AppLovinManager.shared.getOpenAppDuration():MP_AdMobManager.shared.getOpenAppDuration()
|
||||
if duration >= times {
|
||||
MP_AdMobManager.shared.showOpenAdIfAvailable(.HOST, completion: nil)
|
||||
MP_ADSimpleManager.shared.showOpenAdIfAvailable(.HOST, completion: nil)
|
||||
//超过间隔时长,进行热启动广告展示
|
||||
print("返回前台,并展示了热启动广告")
|
||||
}else {
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "img_v3_02em_7d9ebc7f-0fde-40e7-ab5d-5b1c24a8ddbg.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "img_v3_02em_7d9ebc7f-0fde-40e7-ab5d-5b1c24a8ddbg 1.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
@ -7,8 +7,9 @@
|
||||
|
||||
import UIKit
|
||||
import GoogleMobileAds
|
||||
import AppLovinSDK
|
||||
///启动页
|
||||
class MP_LunchViewController: UIViewController, GADFullScreenContentDelegate {
|
||||
class MP_LunchViewController: UIViewController {
|
||||
@IBOutlet weak var progressView: MP_Lunch_ProgressView!{
|
||||
didSet{
|
||||
progressView.layer.masksToBounds = true
|
||||
@ -131,13 +132,13 @@ class MP_LunchViewController: UIViewController, GADFullScreenContentDelegate {
|
||||
MPPositive_BrowseLoadViewModel.shared.reloadBrowseLists()
|
||||
}
|
||||
}
|
||||
MP_AdMobManager.shared.loadMoreAdMobs()
|
||||
MP_AdMobManager.shared.showOpenAdIfAvailable(.ICE) { [weak self] (ad, isOpen) in
|
||||
MP_ADSimpleManager.shared.loadMoreAds()
|
||||
MP_ADSimpleManager.shared.showOpenAdIfAvailable(.ICE) { [weak self] (ad, isOpen, platform) in
|
||||
guard let self = self else {return}
|
||||
addValue = 3
|
||||
//将广告事件传递闭包赋值
|
||||
adShowBlock = {
|
||||
self.adPresent(ad: ad, isOpen: isOpen)
|
||||
self.adPresent(ad: ad, isOpen: isOpen, platform: platform)
|
||||
}
|
||||
}
|
||||
//进入过B面
|
||||
@ -170,13 +171,13 @@ class MP_LunchViewController: UIViewController, GADFullScreenContentDelegate {
|
||||
guard let self = self else {return}
|
||||
if open {
|
||||
//开关检测为通过,以下发ID刷新广告
|
||||
MP_AdMobManager.shared.loadMoreAdMobs()
|
||||
MP_AdMobManager.shared.showOpenAdIfAvailable(.ICE) { [weak self] (ad,isOpen) in
|
||||
MP_ADSimpleManager.shared.loadMoreAds()
|
||||
MP_ADSimpleManager.shared.showOpenAdIfAvailable(.ICE) { [weak self] (ad, isOpen, platform) in
|
||||
guard let self = self else {return}
|
||||
addValue = 3
|
||||
//将广告事件传递闭包赋值
|
||||
adShowBlock = {
|
||||
self.adPresent(ad: ad, isOpen: isOpen)
|
||||
self.adPresent(ad: ad, isOpen: isOpen, platform: platform)
|
||||
}
|
||||
}
|
||||
//根据ip值确定进入那个页面
|
||||
@ -258,13 +259,13 @@ class MP_LunchViewController: UIViewController, GADFullScreenContentDelegate {
|
||||
}
|
||||
}else {
|
||||
//开关检测未通过,以默认ID刷新广告
|
||||
MP_AdMobManager.shared.loadMoreAdMobs()
|
||||
MP_AdMobManager.shared.showOpenAdIfAvailable(.ICE) { [weak self] (ad,isOpen) in
|
||||
MP_ADSimpleManager.shared.loadMoreAds()
|
||||
MP_ADSimpleManager.shared.showOpenAdIfAvailable(.ICE) { [weak self] (ad, isOpen, platform) in
|
||||
guard let self = self else {return}
|
||||
addValue = 3
|
||||
//将广告事件传递闭包赋值
|
||||
adShowBlock = {
|
||||
self.adPresent(ad: ad, isOpen: isOpen)
|
||||
self.adPresent(ad: ad, isOpen: isOpen, platform: platform)
|
||||
}
|
||||
}
|
||||
print("ALog")
|
||||
@ -299,43 +300,94 @@ class MP_LunchViewController: UIViewController, GADFullScreenContentDelegate {
|
||||
}
|
||||
}
|
||||
//广告弹出
|
||||
private func adPresent(ad: GADFullScreenPresentingAd, isOpen:Bool) {
|
||||
private func adPresent(ad: AnyObject, isOpen:Bool, platform:Bool) {
|
||||
DispatchQueue.main.async {
|
||||
//printCallStack()
|
||||
//修改插页总开关状态
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
MP_AdMobManager.shared.isShowingOpenAd = true
|
||||
if isOpen {
|
||||
let new = ad as? GADAppOpenAd
|
||||
//覆盖并实现代理
|
||||
new?.fullScreenContentDelegate = self
|
||||
do{
|
||||
try new?.canPresent(fromRootViewController: self)
|
||||
new?.present(fromRootViewController: self)
|
||||
}catch{
|
||||
print("开屏广告展示失败,失败原因:\(error)")
|
||||
if MP_AdMobManager.shared.completeOpenAdBlock != nil {
|
||||
MP_AdMobManager.shared.completeOpenAdBlock!()
|
||||
}
|
||||
|
||||
}
|
||||
if platform {
|
||||
//修改插页总开关状态
|
||||
MP_AppLovinManager.shared.setInterstitialSwitch(true)
|
||||
MP_AppLovinManager.shared.isShowingOpenAd = true
|
||||
//展示广告
|
||||
let new = ad as? MAInterstitialAd
|
||||
new?.delegate = self
|
||||
new?.show()
|
||||
}else {
|
||||
let new = ad as? GADInterstitialAd
|
||||
//覆盖并实现代理
|
||||
new?.fullScreenContentDelegate = self
|
||||
do{
|
||||
try new?.canPresent(fromRootViewController: self)
|
||||
new?.present(fromRootViewController: self)
|
||||
}catch{
|
||||
print("开屏广告展示失败,失败原因:\(error)")
|
||||
if MP_AdMobManager.shared.completeOpenAdBlock != nil {
|
||||
MP_AdMobManager.shared.completeOpenAdBlock!()
|
||||
}
|
||||
//修改插页总开关状态
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
MP_AdMobManager.shared.isShowingOpenAd = true
|
||||
if isOpen {
|
||||
let new = ad as? GADAppOpenAd
|
||||
//覆盖并实现代理
|
||||
new?.fullScreenContentDelegate = self
|
||||
do{
|
||||
try new?.canPresent(fromRootViewController: self)
|
||||
new?.present(fromRootViewController: self)
|
||||
}catch{
|
||||
print("开屏广告展示失败,失败原因:\(error)")
|
||||
if MP_AdMobManager.shared.completeOpenAdBlock != nil {
|
||||
MP_AdMobManager.shared.completeOpenAdBlock!()
|
||||
}
|
||||
|
||||
}
|
||||
}else {
|
||||
let new = ad as? GADInterstitialAd
|
||||
//覆盖并实现代理
|
||||
new?.fullScreenContentDelegate = self
|
||||
do{
|
||||
try new?.canPresent(fromRootViewController: self)
|
||||
new?.present(fromRootViewController: self)
|
||||
}catch{
|
||||
print("开屏广告展示失败,失败原因:\(error)")
|
||||
if MP_AdMobManager.shared.completeOpenAdBlock != nil {
|
||||
MP_AdMobManager.shared.completeOpenAdBlock!()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
extension MP_LunchViewController: GADFullScreenContentDelegate, MAAdDelegate{
|
||||
func didLoad(_ ad: MAAd) {
|
||||
}
|
||||
|
||||
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
|
||||
}
|
||||
|
||||
func didDisplay(_ ad: MAAd) {
|
||||
if ad.adUnitIdentifier == MP_AppLovinManager.shared.appOpenAd?.adUnitIdentifier {
|
||||
print("当前展示的广告是开屏广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
//上传成功事件
|
||||
MP_AnalyticsManager.shared.max_lunch_showSuccessAction()
|
||||
}
|
||||
}
|
||||
|
||||
func didHide(_ ad: MAAd) {
|
||||
//当前启动页,展示广告一定是开屏广告
|
||||
if switchBlock != nil {
|
||||
switchBlock!()
|
||||
}
|
||||
if MP_AppLovinManager.shared.completeOpenAdBlock != nil {
|
||||
MP_AppLovinManager.shared.completeOpenAdBlock!()
|
||||
}
|
||||
print("冷启动广告关闭")
|
||||
MP_AnalyticsManager.shared.cold_ads_closeAction()
|
||||
}
|
||||
|
||||
func didClick(_ ad: MAAd) {
|
||||
}
|
||||
|
||||
func didFail(toDisplay ad: MAAd, withError error: MAError) {
|
||||
//当前启动页,展示广告一定是开屏广告
|
||||
if switchBlock != nil {
|
||||
switchBlock!()
|
||||
}
|
||||
MP_AnalyticsManager.shared.max_lunch_showFailureAction(error.message)
|
||||
if MP_AppLovinManager.shared.completeOpenAdBlock != nil {
|
||||
MP_AppLovinManager.shared.completeOpenAdBlock!()
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - 覆盖型广告代理 GADFullScreenContentDelegate
|
||||
//覆盖型广告将要将要展示
|
||||
func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||||
|
||||
116
relax.offline.mp3.music/MP/Common/Extension(扩展)/Devices.swift
Normal file
116
relax.offline.mp3.music/MP/Common/Extension(扩展)/Devices.swift
Normal file
@ -0,0 +1,116 @@
|
||||
//
|
||||
// Devices.swift
|
||||
// relax.offline.mp3.music
|
||||
//
|
||||
// Created by Mr.Zhou on 2024/9/14.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UIDevice {
|
||||
var modelName: String {
|
||||
var systemInfo = utsname()
|
||||
uname(&systemInfo)
|
||||
let machineMirror = Mirror(reflecting: systemInfo.machine)
|
||||
let identifier = machineMirror.children.reduce("") { identifier, element in
|
||||
guard let value = element.value as? Int8, value != 0 else { return identifier }
|
||||
return identifier + String(UnicodeScalar(UInt8(value)))
|
||||
}
|
||||
|
||||
return mapToDevice(identifier: identifier)
|
||||
}
|
||||
|
||||
private func mapToDevice(identifier: String) -> String {
|
||||
#if os(iOS)
|
||||
switch identifier {
|
||||
case "iPhone1,1": return "iPhone"
|
||||
case "iPhone1,2": return "iPhone 3G"
|
||||
case "iPhone2,1": return "iPhone 3GS"
|
||||
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4"
|
||||
case "iPhone4,1", "iPhone4,2", "iPhone4,3": return "iPhone 4S"
|
||||
case "iPhone5,1", "iPhone5,2": return "iPhone 5"
|
||||
case "iPhone5,3", "iPhone5,4": return "iPhone 5C"
|
||||
case "iPhone6,1", "iPhone6,2": return "iPhone 5S"
|
||||
case "iPhone7,2": return "iPhone 6"
|
||||
case "iPhone7,1": return "iPhone 6 Plus"
|
||||
case "iPhone8,1": return "iPhone 6S"
|
||||
case "iPhone8,2": return "iPhone 6S Plus"
|
||||
case "iPhone8,4": return "iPhone SE"
|
||||
case "iPhone9,1", "iPhone9,3": return "iPhone 7"
|
||||
case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus"
|
||||
case "iPhone10,1", "iPhone10,4": return "iPhone 8"
|
||||
case "iPhone10,2", "iPhone10,5": return "iPhone 8 Plus"
|
||||
case "iPhone10,3", "iPhone10,6": return "iPhone X"
|
||||
case "iPhone11,2": return "iPhone Xs"
|
||||
case "iPhone11,4", "iPhone11,6": return "iPhone Xs Max"
|
||||
case "iPhone11,8": return "iPhone Xʀ"
|
||||
case "iPhone12,1": return "iPhone 11"
|
||||
case "iPhone12,3": return "iPhone 11 Pro"
|
||||
case "iPhone12,5": return "iPhone 11 Pro Max"
|
||||
case "iPhone12,8": return "iPhone SE 2"
|
||||
case "iPhone13,1": return "iPhone 12 mini"
|
||||
case "iPhone13,2": return "iPhone 12"
|
||||
case "iPhone13,3": return "iPhone 12 Pro"
|
||||
case "iPhone13,4": return "iPhone 12 Pro Max"
|
||||
case "iPhone14,4": return "iPhone 13 mini"
|
||||
case "iPhone14,5": return "iPhone 13"
|
||||
case "iPhone14,2": return "iPhone 13 Pro"
|
||||
case "iPhone14,3": return "iPhone 13 Pro Max"
|
||||
case "iPhone14,6": return "iPhone SE 3"
|
||||
case "iPhone14,7": return "iPhone 14"
|
||||
case "iPhone14,8": return "iPhone 14 Plus"
|
||||
case "iPhone15,2": return "iPhone 14 Pro"
|
||||
case "iPhone15,3": return "iPhone 14 Pro Max"
|
||||
case "iPhone15,4": return "iPhone 15"
|
||||
case "iPhone15,5": return "iPhone 15 Plus"
|
||||
case "iPhone16,1": return "iPhone 15 Pro"
|
||||
case "iPhone16,2": return "iPhone 15 Pro Max"
|
||||
case "iPhone17,3": return "iPhone 16"
|
||||
case "iPhone17,4": return "iPhone 16 Plus"
|
||||
case "iPhone17,1": return "iPhone 16 Pro"
|
||||
case "iPhone17,2": return "iPhone 16 Pro Max"
|
||||
// iPad
|
||||
case "iPad1,1": return "iPad"
|
||||
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return "iPad 2"
|
||||
case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad (3rd generation)"
|
||||
case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad (4th generation)"
|
||||
case "iPad6,11", "iPad6,12": return "iPad (5th generation)"
|
||||
case "iPad7,5", "iPad7,6": return "iPad (6th generation)"
|
||||
case "iPad7,11", "iPad7,12": return "iPad (7th generation)"
|
||||
case "iPad11,6", "iPad11,7": return "iPad (8th generation)"
|
||||
case "iPad12,1", "iPad12,2": return "iPad (9th generation)"
|
||||
case "iPad13,18", "iPad13,19": return "iPad (10th generation)"
|
||||
// iPad Air
|
||||
case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air"
|
||||
case "iPad5,3", "iPad5,4": return "iPad Air 2"
|
||||
case "iPad11,3", "iPad11,4": return "iPad Air (3rd generation)"
|
||||
case "iPad13,1", "iPad13,2": return "iPad Air (4th generation)"
|
||||
case "iPad13,16", "iPad13,17": return "iPad Air (5th generation)"
|
||||
// iPad mini
|
||||
case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad mini"
|
||||
case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad mini 2"
|
||||
case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad mini 3"
|
||||
case "iPad5,1", "iPad5,2": return "iPad mini 4"
|
||||
case "iPad11,1", "iPad11,2": return "iPad mini (5th generation)"
|
||||
case "iPad14,1", "iPad14,2": return "iPad mini (6th generation)"
|
||||
// iPad Pro
|
||||
case "iPad6,7", "iPad6,8": return "iPad Pro (12.9-inch)"
|
||||
case "iPad6,3", "iPad6,4": return "iPad Pro (9.7-inch)"
|
||||
case "iPad7,1", "iPad7,2": return "iPad Pro (12.9-inch, 2nd generation)"
|
||||
case "iPad7,3", "iPad7,4": return "iPad Pro (10.5-inch)"
|
||||
case "iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4": return "iPad Pro (11-inch, 1st generation)"
|
||||
case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8": return "iPad Pro (12.9-inch, 3rd generation)"
|
||||
case "iPad8,9", "iPad8,10": return "iPad Pro (11-inch, 2nd generation)"
|
||||
case "iPad8,11", "iPad8,12": return "iPad Pro (12.9-inch, 4th generation)"
|
||||
case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7": return "iPad Pro (11-inch, 3rd generation)"
|
||||
case "iPad13,8", "iPad13,9", "iPad13,10", "iPad13,11": return "iPad Pro (12.9-inch, 5th generation)"
|
||||
case "iPad14,3", "iPad14,4": return "iPad Pro (11-inch, 4th generation)"
|
||||
case "iPad14,5", "iPad14,6": return "iPad Pro (12.9-inch, 6th generation)"
|
||||
// Add more cases here as needed
|
||||
default: return identifier
|
||||
}
|
||||
#else
|
||||
return identifier
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "ليس الآن";
|
||||
///更新提醒
|
||||
"Update available" = "تحديث متاح";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "أنت في وضع عدم الاتصال بالإنترنت";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "تم نسخ عنوان البريد الإلكتروني بنجاح إلى الحافظة";
|
||||
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "Nicht jetzt";
|
||||
///更新提醒
|
||||
"Update available" = "Aktualisierung verfügbar";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "Sie befinden sich im Offline-Modus";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "E-Mail-Adresse erfolgreich in die Zwischenablage kopiert";
|
||||
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "Not now";
|
||||
///更新提醒
|
||||
"Update available" = "Update available";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "You are in offline mode";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "Successfully copied the e-mail address to the clipboard";
|
||||
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "Ahora no";
|
||||
///更新提醒
|
||||
"Update available" = "Actualización disponible";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "Estás en modo fuera de línea";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "Dirección de correo electrónico copiada correctamente al portapapeles";
|
||||
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "Pas maintenant";
|
||||
///更新提醒
|
||||
"Update available" = "Mise à jour disponible";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "Vous êtes en mode hors ligne";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "Adresse e-mail copiée avec succès dans le presse-papiers";
|
||||
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "Non ora";
|
||||
///更新提醒
|
||||
"Update available" = "Aggiornamento disponibile";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "Sei in modalità offline";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "Indirizzo email copiato con successo negli appunti";
|
||||
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "Não agora";
|
||||
///更新提醒
|
||||
"Update available" = "Atualização disponível";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "Você está no modo offline";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "Endereço de e-mail copiado com sucesso para a área de transferência";
|
||||
|
||||
@ -142,6 +142,8 @@
|
||||
"Not now" = "Şimdi değil";
|
||||
///更新提醒
|
||||
"Update available" = "Güncelleme mevcut";
|
||||
///切换至离线歌单
|
||||
"You are in offline mode" = "Çevrimdışı moddasınız";
|
||||
//MARK: - HUD文本
|
||||
///已成功将电子邮件地址复制到剪贴板
|
||||
"Successfully copied the e-mail address to the clipboard" = "Herhangi bir yorumunuz veya öneriniz varsa lütfen aşağıdaki e-posta adresinden bizimle iletişime geçin.";
|
||||
|
||||
@ -174,6 +174,34 @@ func coreDefaultValues() {
|
||||
UserDefaults.standard.set(array, forKey: "LibraryNATIVEID")
|
||||
}
|
||||
}
|
||||
if UserDefaults.standard.object(forKey: "Max_OpenICEIDs") == nil {
|
||||
if let array = coreAdModelforJson([.init(level: 3, identifier: "1dd2cf325a0eb64d", ad: "AppLovin", type: .Insert)]) {
|
||||
//存入默认开屏热启动广告ID
|
||||
UserDefaults.standard.set(array, forKey: "Max_OpenICEIDs")
|
||||
}
|
||||
}
|
||||
if UserDefaults.standard.object(forKey: "Max_SearchINSERTIDs") == nil {
|
||||
if let array = coreAdModelforJson([.init(level: 3, identifier: "43414b9a63224bc6", ad: "AppLovin", type: .Insert)]) {
|
||||
//存入默认开屏热启动广告ID
|
||||
UserDefaults.standard.set(array, forKey: "Max_SearchINSERTIDs")
|
||||
}
|
||||
}
|
||||
if UserDefaults.standard.object(forKey: "Max_PlayerINSERTIDs") == nil {
|
||||
if let array = coreAdModelforJson([.init(level: 3, identifier: "e13ab66866fd6bf8", ad: "AppLovin", type: .Insert)]) {
|
||||
//存入默认开屏热启动广告ID
|
||||
UserDefaults.standard.set(array, forKey: "Max_PlayerINSERTIDs")
|
||||
}
|
||||
}
|
||||
if UserDefaults.standard.object(forKey: "Max_LibraryNATIVEIDs") == nil {
|
||||
if let array = coreAdModelforJson([.init(level: 3, identifier: "4f3858556dc405ee", ad: "AppLovin", type: .Insert)]) {
|
||||
//存入默认开屏热启动广告ID
|
||||
UserDefaults.standard.set(array, forKey: "Max_LibraryNATIVEIDs")
|
||||
}
|
||||
}
|
||||
if UserDefaults.standard.object(forKey: "platform") == nil {
|
||||
UserDefaults.standard.set(false, forKey: "platform")
|
||||
}
|
||||
|
||||
//更多内容操作
|
||||
if UserDefaults.standard.string(forKey: "ClientVersion") == nil {
|
||||
UserDefaults.standard.set("1.20240618.01.00", forKey: "ClientVersion")
|
||||
@ -205,7 +233,7 @@ func coreDefaultValues() {
|
||||
}
|
||||
}
|
||||
///将广告模型组转为Data
|
||||
func coreAdModelforJson(_ array:[MPPositive_AdModelModel]) -> Data? {
|
||||
func coreAdModelforJson(_ array:[MPPositive_AdItemModel]) -> Data? {
|
||||
guard array.isEmpty != true else {return nil}
|
||||
do{
|
||||
let jsonData = try JSONEncoder().encode(array)
|
||||
@ -217,9 +245,9 @@ func coreAdModelforJson(_ array:[MPPositive_AdModelModel]) -> Data? {
|
||||
}
|
||||
}
|
||||
///将data转为广告模型组
|
||||
func jsonforCoreAdModel(_ data:Data) -> [MPPositive_AdModelModel]? {
|
||||
func jsonforCoreAdModel(_ data:Data) -> [MPPositive_AdItemModel]? {
|
||||
do{
|
||||
let array:[MPPositive_AdModelModel] = try JSONDecoder().decode([MPPositive_AdModelModel].self, from: data)
|
||||
let array:[MPPositive_AdItemModel] = try JSONDecoder().decode([MPPositive_AdItemModel].self, from: data)
|
||||
return array
|
||||
}catch{
|
||||
//编译失败
|
||||
@ -265,10 +293,12 @@ func improveDataforLycirsAndRelated(_ song:MPPositive_SongItemModel, completion:
|
||||
}
|
||||
}
|
||||
///调用player对资源路径和封面路径补全
|
||||
func improveDataforResouceAndCover(_ song:MPPositive_SongItemModel, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void)) {
|
||||
func improveDataforResouceAndCover(_ song:MPPositive_SongItemModel, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void), failure: ((Bool) -> Void)? = nil) {
|
||||
//单曲补全需要调用player接口
|
||||
MP_NetWorkManager.shared.requestAndroidPlayer(song.videoId ?? "", playlistId: "", clickTrackingParams: song.clickTrackingParams ?? "") { resourceUrls, coverUrls in
|
||||
completion(resourceUrls,coverUrls)
|
||||
} failure: {statu in
|
||||
failure?(statu)
|
||||
}
|
||||
}
|
||||
///转时分值
|
||||
@ -535,3 +565,43 @@ func postUpdateReminder(_ observe:UIViewController) {
|
||||
MP_AnalyticsManager.shared.update_reminder_showAction()
|
||||
observe.present(alter, animated: true)
|
||||
}
|
||||
///从离线第一首开始播放
|
||||
func playOfflineSongs() {
|
||||
if MPPositive_LoadCoreModel.shared.loadViewModels.isEmpty == false {
|
||||
MP_HUD.text("You are in offline mode".localizableString(), delay: 2.0, completion: nil)
|
||||
//获取离线的歌曲
|
||||
MP_AnalyticsManager.shared.song_clickAction("Offline Song")
|
||||
//优先清除数据
|
||||
MP_PlayerManager.shared.loadPlayer = nil
|
||||
//弹出播放器
|
||||
NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
|
||||
MP_AnalyticsManager.shared.player_b_impAction()
|
||||
//将当前下载音乐放入列表中
|
||||
var array:[MPPositive_SongItemModel] = []
|
||||
for (index, song) in MPPositive_LoadCoreModel.shared.loadViewModels.enumerated() {
|
||||
let item = MPPositive_SongItemModel()
|
||||
item.index = index
|
||||
item.coverUrls = [song.loadItem.coverImage ?? ""]
|
||||
item.reviewUrls = [song.loadItem.reviewImage ?? ""]
|
||||
item.title = song.loadItem.title
|
||||
item.longBylineText = song.loadItem.longBylineText
|
||||
item.lengthText = song.loadItem.lengthText
|
||||
item.shortBylineText = song.loadItem.shortBylineText
|
||||
item.lyricsID = song.loadItem.lyricsID
|
||||
item.lyrics = song.loadItem.lyrics
|
||||
item.videoId = song.loadItem.videoId
|
||||
item.relatedID = song.loadItem.relatedID
|
||||
array.append(item)
|
||||
}
|
||||
if let currentVideo = MPPositive_LoadCoreModel.shared.loadViewModels.first {
|
||||
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.loadItem.videoId ?? "")
|
||||
lodaViewModel.improveData(currentVideo.loadItem.videoId ?? "")
|
||||
//更改播放器播放类型
|
||||
MP_PlayerManager.shared.setPlayType(.normal)
|
||||
MP_PlayerManager.shared.loadPlayer = lodaViewModel
|
||||
MP_AnalyticsManager.shared.player_b_listAction()
|
||||
}
|
||||
}else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,12 +11,16 @@ class MPPositive_Debouncer: NSObject {
|
||||
static let shared = MPPositive_Debouncer()
|
||||
//计时器
|
||||
private var timer: Timer?
|
||||
//播放器计时器
|
||||
private var playerTimer:Timer?
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
deinit {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
playerTimer?.invalidate()
|
||||
playerTimer = nil
|
||||
}
|
||||
func call(_ delay:TimeInterval = 0.15, action:@escaping (() -> Void)) {
|
||||
// 取消之前的延迟调用
|
||||
@ -27,4 +31,11 @@ class MPPositive_Debouncer: NSObject {
|
||||
action()
|
||||
}
|
||||
}
|
||||
func playCall(_ action:@escaping (() -> Void)) {
|
||||
playerTimer?.invalidate()
|
||||
playerTimer = nil
|
||||
playerTimer = Timer.scheduledTimer(withTimeInterval: 10, repeats: false) { _ in
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,198 @@
|
||||
//
|
||||
// MP_ADSimpleManager.swift
|
||||
// relax.offline.mp3.music
|
||||
//
|
||||
// Created by Mr.Zhou on 2024/9/19.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
import GoogleMobileAds
|
||||
import AppLovinAdapter
|
||||
import AppLovinSDK
|
||||
import LiftoffMonetizeAdapter
|
||||
import VungleAdsSDK
|
||||
import PangleAdapter
|
||||
import PAGAdSDK
|
||||
import IronSourceAdapter
|
||||
import IronSource
|
||||
import MintegralAdapter
|
||||
import MTGSDK
|
||||
import ChartboostSDK
|
||||
import ChartboostAdapter
|
||||
//开屏广告类型
|
||||
enum OpenType:Int {
|
||||
//冷启动
|
||||
case ICE = 0
|
||||
//热启动
|
||||
case HOST = 1
|
||||
var title:String{
|
||||
switch self {
|
||||
case .ICE:
|
||||
return "是冷启动开屏广告"
|
||||
case .HOST:
|
||||
return "是热启动开屏广告"
|
||||
}
|
||||
}
|
||||
}
|
||||
///广告中央管理器
|
||||
class MP_ADSimpleManager: NSObject {
|
||||
static let shared = MP_ADSimpleManager()
|
||||
//调用的广告平台, false为AdMob,ture为AppLovin
|
||||
var platform:Bool{
|
||||
if let newValue = UserDefaults.standard.object(forKey: "platform") as? Bool {
|
||||
return newValue
|
||||
}else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
///广告总开关
|
||||
var openAdStatus:Bool = true
|
||||
///内部使用广告开光
|
||||
var internalAdStatus:Bool = true
|
||||
///设置广告总开关
|
||||
func setOpenAdStatus(_ bool:Bool) {
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
openAdStatus = bool
|
||||
}
|
||||
}
|
||||
///插页广告总开关
|
||||
private var interstitialSwitch:Bool {
|
||||
get {
|
||||
if platform {
|
||||
return MP_AppLovinManager.shared.getInterstitialSwitch()
|
||||
}else {
|
||||
return MP_AdMobManager.shared.getInterstitialSwitch()
|
||||
}
|
||||
}
|
||||
}
|
||||
///获得插页开关的状态
|
||||
func getInterstitialSwitch() -> Bool {
|
||||
return interstitialSwitch
|
||||
}
|
||||
override init() {
|
||||
super.init()
|
||||
NotificationCenter.notificationKey.add(observer: self, selector: #selector(netWorkReachableAction(_:)), notificationName: .net_switch_reachable)
|
||||
}
|
||||
deinit{
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
//启动广告初始化
|
||||
func start() {
|
||||
MP_AdMobManager.shared.start()
|
||||
MP_AppLovinManager.shared.startConfig()
|
||||
}
|
||||
|
||||
//网络可用时触发
|
||||
@objc private func netWorkReachableAction(_ sender:Notification) {
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
if platform {
|
||||
MP_AppLovinManager.shared.loadMoreAds()
|
||||
}else {
|
||||
MP_AdMobManager.shared.loadMoreAdMobs()
|
||||
}
|
||||
}
|
||||
}
|
||||
//加载更多广告
|
||||
func loadMoreAds() {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
if platform {
|
||||
MP_AppLovinManager.shared.loadMoreAds()
|
||||
}else {
|
||||
MP_AdMobManager.shared.loadMoreAdMobs()
|
||||
}
|
||||
}
|
||||
///展示开屏广告
|
||||
func showOpenAdIfAvailable(_ type:OpenType, completion:((_ ad:AnyObject, _ isOpen:Bool, _ platform:Bool) -> Void)?) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
if platform {
|
||||
if let block = completion {
|
||||
MP_AppLovinManager.shared.showOpenAdIfAvailable {[weak self] ad in
|
||||
guard let self = self else {return}
|
||||
block(ad, false, true)
|
||||
}
|
||||
}else {
|
||||
MP_AppLovinManager.shared.showOpenAdIfAvailable(nil)
|
||||
}
|
||||
}else {
|
||||
if let block = completion {
|
||||
MP_AdMobManager.shared.showOpenAdIfAvailable(type) { [weak self] ad, isOpen in
|
||||
guard let self = self else {return}
|
||||
block(ad, isOpen, false)
|
||||
}
|
||||
}else {
|
||||
MP_AdMobManager.shared.showOpenAdIfAvailable(type, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
///展示搜索广告
|
||||
func showSearchInterstitialAdIfAvailable(completion:((AnyObject, Bool) -> Void)?) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
if platform {
|
||||
if let block = completion {
|
||||
MP_AppLovinManager.shared.showSearchInterstitialAdIfAvailable { ad in
|
||||
block(ad, true)
|
||||
}
|
||||
}else {
|
||||
MP_AppLovinManager.shared.showSearchInterstitialAdIfAvailable(nil)
|
||||
}
|
||||
}else {
|
||||
if let block = completion {
|
||||
MP_AdMobManager.shared.showSearchInterstitialAdIfAvailable { ad in
|
||||
block(ad, false)
|
||||
}
|
||||
}else {
|
||||
MP_AdMobManager.shared.showSearchInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
///展示播放广告
|
||||
func showPlayInterstitialAdIfAvailable(_ completion:((AnyObject?, Bool) -> Void)?) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
if platform {
|
||||
if let block = completion {
|
||||
MP_AppLovinManager.shared.showPlayInterstitialAdIfAvailable { ad in
|
||||
block(ad, true)
|
||||
}
|
||||
}else {
|
||||
MP_AppLovinManager.shared.showPlayInterstitialAdIfAvailable(nil)
|
||||
}
|
||||
}else {
|
||||
if let block = completion {
|
||||
MP_AdMobManager.shared.showPlayInterstitialAdIfAvailable { ad in
|
||||
block(ad, false)
|
||||
}
|
||||
}else {
|
||||
MP_AdMobManager.shared.showPlayInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
///展示曲库广告
|
||||
func showLibraryInterstitialAdIfAvailable(completion:((AnyObject) -> Void)?) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
if platform {
|
||||
if let block = completion {
|
||||
MP_AppLovinManager.shared.showLibraryInterstitialAdIfAvailable { ad in
|
||||
block(ad)
|
||||
}
|
||||
}else {
|
||||
MP_AppLovinManager.shared.showLibraryInterstitialAdIfAvailable(nil)
|
||||
}
|
||||
}else {
|
||||
if let block = completion {
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable { ad in
|
||||
block(ad)
|
||||
}
|
||||
}else {
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,23 +21,15 @@ import MTGSDK
|
||||
import ChartboostSDK
|
||||
import ChartboostAdapter
|
||||
|
||||
///广告管理器
|
||||
///AdMob广告管理器
|
||||
class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenContentDelegate, GADNativeAdLoaderDelegate, GADNativeAdDelegate, GADVideoControllerDelegate {
|
||||
static let shared = MP_AdMobManager()
|
||||
private let sharedInstance = GADMobileAds.sharedInstance()
|
||||
///广告总开关
|
||||
private var openAdStatus:Bool = true
|
||||
private var openAdStatus:Bool = MP_ADSimpleManager.shared.openAdStatus
|
||||
///内部使用广告开光
|
||||
private var internalAdStatus:Bool = true
|
||||
private var internalAdStatus:Bool = MP_ADSimpleManager.shared.internalAdStatus
|
||||
|
||||
///设置广告总开关
|
||||
func setOpenAdStatus(_ bool:Bool) {
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
openAdStatus = bool
|
||||
}
|
||||
}
|
||||
private let sharedInstance = GADMobileAds.sharedInstance()
|
||||
///广告过期时间(50分钟)
|
||||
private let expirationTime:TimeInterval = 3000
|
||||
|
||||
@ -53,7 +45,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
didSet{
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
// MP_PlayerManager.shared.isAdLate = self?.interstitialSwitch
|
||||
MPSideA_MediaCenterManager.shared.isAdLate = self?.interstitialSwitch
|
||||
}
|
||||
}
|
||||
@ -326,7 +317,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
}
|
||||
///加载更多广告
|
||||
func loadMoreAdMobs() {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
loadPlayInterstitialAd{status in
|
||||
if status {
|
||||
print("成功加载播放插页广告")
|
||||
@ -341,13 +331,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
print("搜索插页广告加载失败")
|
||||
}
|
||||
}
|
||||
// loadSwitchInterstitialAd { status in
|
||||
// if status {
|
||||
// print("成功加载切歌插页广告")
|
||||
// }else {
|
||||
// print("切歌插页广告加载失败")
|
||||
// }
|
||||
// }
|
||||
loadLibraryInterstitialAd { status in
|
||||
if status {
|
||||
print("成功加载曲库插页广告")
|
||||
@ -356,20 +339,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
}
|
||||
|
||||
}
|
||||
// loadGlobalInterstitialAd { status in
|
||||
// if status {
|
||||
// print("成功加载全局插页广告")
|
||||
// }else {
|
||||
// print("全局插页广告加载失败")
|
||||
// }
|
||||
// }
|
||||
// loadLoadInterstitialAd { status in
|
||||
// if status {
|
||||
// print("成功加载下载插页广告")
|
||||
// }else {
|
||||
// print("下载插页广告加载失败")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//网络可用时触发
|
||||
@objc private func netWorkReachableAction(_ sender:Notification) {
|
||||
@ -411,24 +380,9 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
}
|
||||
//MARK: - 开屏
|
||||
//开屏冷启动广告ID
|
||||
private var OpenICEID:[MPPositive_AdModelModel] = []
|
||||
private var OpenICEID:[MPPositive_AdItemModel] = []
|
||||
//开屏热启动广告ID
|
||||
private var OpenHOSTID:[MPPositive_AdModelModel] = []
|
||||
//开屏广告类型
|
||||
enum OpenType:Int {
|
||||
//冷启动
|
||||
case ICE = 0
|
||||
//热启动
|
||||
case HOST = 1
|
||||
var title:String{
|
||||
switch self {
|
||||
case .ICE:
|
||||
return "是冷启动开屏广告"
|
||||
case .HOST:
|
||||
return "是热启动开屏广告"
|
||||
}
|
||||
}
|
||||
}
|
||||
private var OpenHOSTID:[MPPositive_AdItemModel] = []
|
||||
//应用开屏广告实例
|
||||
var appOpenAd:GADAppOpenAd?
|
||||
//应用插页广告实例
|
||||
@ -439,7 +393,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
var isShowingOpenAd:Bool = false
|
||||
//开屏广告加载时间
|
||||
private var loadOpenAdTime:Date?
|
||||
//开屏广告时间间隔(默认5秒)
|
||||
//开屏广告时间间隔(默认10秒)
|
||||
private var openAppDuration:TimeInterval{
|
||||
get{
|
||||
if let times = UserDefaults.standard.object(forKey: "OpenAppDuration") as? TimeInterval {
|
||||
@ -470,7 +424,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
return
|
||||
}
|
||||
//检索是否超过了对应的id组的阶级数量
|
||||
var item:MPPositive_AdModelModel
|
||||
var item:MPPositive_AdItemModel
|
||||
switch type {
|
||||
case .ICE:
|
||||
guard OpenICEID.isEmpty == false else {
|
||||
@ -517,13 +471,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
}
|
||||
isLoadingOpenAd = true
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
|
||||
//判断需要生成什么广告
|
||||
if item.type == .Open {
|
||||
@ -673,9 +620,9 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
|
||||
//MARK: - 搜索
|
||||
//搜索插页广告ID
|
||||
private var SearchINSERTID:[MPPositive_AdModelModel] = []
|
||||
private var SearchINSERTID:[MPPositive_AdItemModel] = []
|
||||
//搜索原生广告ID
|
||||
private var SearchNATIVEID:[MPPositive_AdModelModel] = []
|
||||
private var SearchNATIVEID:[MPPositive_AdItemModel] = []
|
||||
///搜索插页广告
|
||||
private var searchInterstitialAd:GADInterstitialAd?
|
||||
///是否正在加载搜索插页广告
|
||||
@ -725,13 +672,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
searchAdLoader = GADAdLoader(adUnitID: first.identifier, rootViewController: vc, adTypes: [.native], options: [multipleAdOptions, imageAdOptions, videoAdOptions])
|
||||
searchAdLoader?.delegate = self
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
searchAdLoader?.load(request)
|
||||
}
|
||||
}
|
||||
@ -814,13 +754,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
isLoadingSearchInterstitialAd = true
|
||||
let item = SearchINSERTID[level]
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
//加载搜索插页广告
|
||||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
@ -889,7 +822,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
|
||||
//MARK: - 播放
|
||||
//播放插页广告ID
|
||||
private var PlayerINSERTID:[MPPositive_AdModelModel] = []
|
||||
private var PlayerINSERTID:[MPPositive_AdItemModel] = []
|
||||
///播放插页广告
|
||||
var playInterstitialAd:GADInterstitialAd?
|
||||
///是否正在加载播放插页广告
|
||||
@ -938,13 +871,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
isLoadingPlayInterstitialAd = true
|
||||
let item = PlayerINSERTID[level]
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
//加载播放插页广告
|
||||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
@ -1025,7 +951,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
|
||||
//MARK: - 切歌
|
||||
//切歌插页广告ID
|
||||
private var SwitchINSERTID:[MPPositive_AdModelModel] = []
|
||||
private var SwitchINSERTID:[MPPositive_AdItemModel] = []
|
||||
///切歌插页广告
|
||||
var switchInterstitialAd:GADInterstitialAd?
|
||||
///是否正在加载切歌插页广告
|
||||
@ -1073,13 +999,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
isLoadingSwitchInterstitialAd = true
|
||||
let item = SwitchINSERTID[level]
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
//加载播放插页广告
|
||||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
@ -1150,7 +1069,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
|
||||
//MARK: - 下载
|
||||
//下载插页广告ID
|
||||
private var LoadINSERTID:[MPPositive_AdModelModel] = []
|
||||
private var LoadINSERTID:[MPPositive_AdItemModel] = []
|
||||
///下载插页广告
|
||||
var loadInterstitialAd:GADInterstitialAd?
|
||||
///是否正在加载下载插页广告
|
||||
@ -1198,13 +1117,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
isLoadingLoadInterstitialAd = true
|
||||
let item = LoadINSERTID[level]
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
//加载下载插页广告
|
||||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
@ -1274,9 +1186,9 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
}
|
||||
//MARK: - 曲库
|
||||
//曲库插页ID
|
||||
private var LibraryINSERTID:[MPPositive_AdModelModel] = []
|
||||
private var LibraryINSERTID:[MPPositive_AdItemModel] = []
|
||||
//曲库原生ID
|
||||
private var LibraryNATIVEID:[MPPositive_AdModelModel] = []
|
||||
private var LibraryNATIVEID:[MPPositive_AdItemModel] = []
|
||||
///曲库插页广告
|
||||
private var libraryInterstitialAd:GADInterstitialAd?
|
||||
///是否正在加载曲库插页广告
|
||||
@ -1333,12 +1245,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
libraryAdLoader?.delegate = self
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
libraryAdLoader?.load(request)
|
||||
libraryNativeAds = []
|
||||
}
|
||||
@ -1446,7 +1352,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
MP_AnalyticsManager.shared.listclk_ads_loadFailureAction("No Ads Fill")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
[weak self] in
|
||||
self?.loadLoadInterstitialAd { status in
|
||||
self?.loadLibraryInterstitialAd { status in
|
||||
if status {
|
||||
print("重新加载曲库插页广告")
|
||||
}else {
|
||||
@ -1459,13 +1365,6 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
isLoadingLibraryInterstitialAd = true
|
||||
let item = LibraryINSERTID[level]
|
||||
let request = GADRequest()
|
||||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||||
// mintegralExtra.muteVideoAudio = true
|
||||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||||
// appLovinExtra.muteAudio = true
|
||||
// request.register(appLovinExtra)
|
||||
// request.register(mintegralExtra)
|
||||
//加载曲库插页广告
|
||||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
@ -1538,7 +1437,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
|
||||
|
||||
//MARK: - 全局
|
||||
//全局备用插页ID
|
||||
private var GlobalINSERTID:[MPPositive_AdModelModel] = []
|
||||
private var GlobalINSERTID:[MPPositive_AdItemModel] = []
|
||||
///全局插页广告
|
||||
private var globalInterstitialAd:GADInterstitialAd?
|
||||
///是否正在加载全局插页广告
|
||||
|
||||
@ -190,6 +190,10 @@ class MP_AnalyticsManager: NSObject {
|
||||
//更新通知
|
||||
scheduleDailyNotifications()
|
||||
}
|
||||
//更新启用的广告平台
|
||||
let platform = self.remoteConfig.configValue(forKey: "platform").boolValue
|
||||
print("广告平台为\(platform ? "AppLovin":"AdMob")")
|
||||
UserDefaults.standard.set(platform, forKey: "platform")
|
||||
//是否需要弹出更新弹窗
|
||||
if let updateReminder = self.remoteConfig.configValue(forKey: "updateReminder").jsonValue as? [String:Any] {
|
||||
//检索是否需要更新
|
||||
@ -229,11 +233,13 @@ class MP_AnalyticsManager: NSObject {
|
||||
if open {
|
||||
//更新广告ID设置-正式版
|
||||
self.reloadAdMobIDs("adMobNewLevelIDs")
|
||||
self.reloadAdMobIDs("maxAdLevelIDs")
|
||||
//进入b面
|
||||
completion(true)
|
||||
}else {
|
||||
//更新广告ID设置-测试版
|
||||
self.reloadAdMobIDs("lowPriceAdModIDs")
|
||||
self.reloadAdMobIDs("maxAdLevelIDs")
|
||||
//进入a面
|
||||
completion(false)
|
||||
}
|
||||
@ -241,6 +247,7 @@ class MP_AnalyticsManager: NSObject {
|
||||
//不是同一个版本,直接进入B面
|
||||
//更新广告ID设置-正式版
|
||||
self.reloadAdMobIDs("adMobNewLevelIDs")
|
||||
self.reloadAdMobIDs("maxAdLevelIDs")
|
||||
completion(true)
|
||||
}
|
||||
}
|
||||
@ -272,14 +279,14 @@ class MP_AnalyticsManager: NSObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
///更新广告配置
|
||||
///更新AdMob广告配置
|
||||
private func reloadAdMobIDs(_ adMob:String) {
|
||||
//根据传入的键值决定使用什么版本的广告ID组
|
||||
//更新广告ID设置
|
||||
if let adTextIDs = self.remoteConfig.configValue(forKey: adMob).jsonValue as? [String:[[String:Any]]] {
|
||||
//对所有广告ID组进行更新
|
||||
for (key, values) in adTextIDs {
|
||||
var array:[MPPositive_AdModelModel] = []
|
||||
var array:[MPPositive_AdItemModel] = []
|
||||
values.forEach { value in
|
||||
if let level = value["level"] as? Int, let identifier = value["identifier"] as? String, let ad = value["ad"] as? String, let item = value["type"] as? String, let type = MPPositive_AdModelType(rawValue: item) {
|
||||
array.append(.init(level: level, identifier: identifier, ad: ad, type: type))
|
||||
@ -631,6 +638,43 @@ class MP_AnalyticsManager: NSObject {
|
||||
//总价值上报
|
||||
private let ad_session_total_value:String = "ad_session_total_value"
|
||||
|
||||
//AppLovin广告上报
|
||||
//启动位展示机会
|
||||
private let max_lunch_chance:String = "max_lunch_chance"
|
||||
//启动位加载失败
|
||||
private let max_lunch_loadFailure:String = "max_lunch_loadFailure"
|
||||
//启动位展示成果
|
||||
private let max_lunch_showSuccess:String = "max_lunch_showSuccess"
|
||||
//启动位展示失败
|
||||
private let max_lunch_showFailure:String = "max_lunch_showFailure"
|
||||
|
||||
//搜索位展示机会
|
||||
private let max_search_chance:String = "max_search_chance"
|
||||
//搜索位加载失败
|
||||
private let max_search_loadFailure:String = "max_search_loadFailure"
|
||||
//搜索位展示成功
|
||||
private let max_search_showSuccess:String = "max_search_showSuccess"
|
||||
//搜索位展示失败
|
||||
private let max_search_showFailure:String = "max_search_showFailure"
|
||||
|
||||
//播放位展示机会
|
||||
private let max_play_chance:String = "max_play_chance"
|
||||
//播放位加载失败
|
||||
private let max_play_loadFailure:String = "max_play_loadFailure"
|
||||
//播放位展示成功
|
||||
private let max_play_showSuccess:String = "max_play_showSuccess"
|
||||
//播放位展示失败
|
||||
private let max_play_showFailure:String = "max_play_showFailure"
|
||||
|
||||
//曲库位展示机会
|
||||
private let max_library_chance:String = "max_library_chance"
|
||||
//曲库位加载失败
|
||||
private let max_library_loadFailure:String = "max_library_loadFailure"
|
||||
//曲库位展示成功
|
||||
private let max_library_showSuccess:String = "max_library_showSuccess"
|
||||
//曲库位展示失败
|
||||
private let max_library_showFailure:String = "max_library_showFailure"
|
||||
|
||||
//插页广告内容值转化
|
||||
private func infoToParameters(_ responseInfo:GADResponseInfo, adValue:GADAdValue) -> [String:Any] {
|
||||
var mediation = "Unknown"
|
||||
@ -888,5 +932,78 @@ class MP_AnalyticsManager: NSObject {
|
||||
let losAngelesTimeString = dateFormatter.string(from: now)
|
||||
return losAngelesTimeString
|
||||
}
|
||||
|
||||
///AppLovin开屏广告展示机会
|
||||
func max_lunch_chanceAction() {
|
||||
Analytics.logEvent(max_lunch_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin开屏广告加载失败
|
||||
func max_lunch_loadFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_lunch_loadFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
///AppLovin开屏广告展示成功
|
||||
func max_lunch_showSuccessAction() {
|
||||
Analytics.logEvent(max_lunch_showSuccess, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin开屏广告展示失败
|
||||
func max_lunch_showFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_lunch_showFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
///AppLovin搜索广告展示机会
|
||||
func max_search_chanceAction() {
|
||||
Analytics.logEvent(max_search_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin搜索广告加载失败
|
||||
func max_search_loadFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_search_loadFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
///AppLovin搜索广告展示成功
|
||||
func max_search_showSuccessAction() {
|
||||
Analytics.logEvent(max_search_showSuccess, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin搜索广告展示失败
|
||||
func max_search_showFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_search_showFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
///AppLovin播放广告展示机会
|
||||
func max_play_chanceACtion() {
|
||||
Analytics.logEvent(max_play_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin播放广告加载失败
|
||||
func max_play_loadFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_play_loadFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
///AppLovin播放广告展示成功
|
||||
func max_play_showSuccessAction() {
|
||||
Analytics.logEvent(max_play_showSuccess, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin播放广告展示失败
|
||||
func max_play_showFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_play_showFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
///AppLovin曲库广告展示机会
|
||||
func max_library_chanceAction() {
|
||||
Analytics.logEvent(max_library_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin曲库广告加载失败
|
||||
func max_library_loadFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_library_loadFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
///AppLovin曲库广告展示成功
|
||||
func max_library_showSuccessAction() {
|
||||
Analytics.logEvent(max_library_showSuccess, parameters: ["CS_STATUS":isOLD ? "Old":"New"])
|
||||
}
|
||||
///AppLovin曲库广告展示失败
|
||||
func max_library_showFailureAction(_ error:String) {
|
||||
Analytics.logEvent(max_library_showFailure, parameters: ["CS_STATUS":isOLD ? "Old":"New",
|
||||
"CS_ERROR":error])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,874 @@
|
||||
//
|
||||
// MP_AppLovinManager.swift
|
||||
// relax.offline.mp3.music
|
||||
//
|
||||
// Created by Mr.Zhou on 2024/9/18.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AppLovinSDK
|
||||
///AppLovin管理器
|
||||
class MP_AppLovinManager: NSObject {
|
||||
static let shared = MP_AppLovinManager()
|
||||
///广告总开关
|
||||
private var openAdStatus:Bool = MP_ADSimpleManager.shared.openAdStatus
|
||||
///内部使用广告开光
|
||||
private var internalAdStatus:Bool = MP_ADSimpleManager.shared.internalAdStatus
|
||||
//AppLovin的SDk密钥
|
||||
private var SDKKey:String {
|
||||
return "1z4AGzagANHydAtmbNQmAcrt1O5_HtPpt4iNTNW5Bb0RQhaXVByUEQTq5cMcR0l9NnfDtuobQqhSQE0kfEWwAC"
|
||||
}
|
||||
///广告过期时间(50分钟)
|
||||
private let expirationTime:TimeInterval = 3000
|
||||
|
||||
//检测广告是否过期
|
||||
private func wasAdexpirationTime(_ date:Date?) -> Bool {
|
||||
guard let loadTime = date else { return false }
|
||||
// Check if ad was loaded more than four hours ago.
|
||||
return Date().timeIntervalSince(loadTime) < expirationTime
|
||||
}
|
||||
//MARK: - 插页广告总设置
|
||||
///插页广告总开关
|
||||
private var interstitialSwitch:Bool = false{
|
||||
didSet{
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
MPSideA_MediaCenterManager.shared.isAdLate = self?.interstitialSwitch
|
||||
}
|
||||
}
|
||||
}
|
||||
///插页广告显示时间
|
||||
var interstitialDate:Date?
|
||||
///插页广告间隔秒数(默认40秒)
|
||||
private var interstitialDuration:TimeInterval{
|
||||
get{
|
||||
if let times = UserDefaults.standard.object(forKey: "InterstitialDuration") as? TimeInterval {
|
||||
return times
|
||||
}else {
|
||||
return 40
|
||||
}
|
||||
}
|
||||
}
|
||||
///中介间隔秒数
|
||||
private var intermediaryDuration:TimeInterval{
|
||||
get{
|
||||
if let times = UserDefaults.standard.object(forKey: "IntermediaryDuration") as? TimeInterval {
|
||||
return times
|
||||
}else {
|
||||
return 40
|
||||
}
|
||||
}
|
||||
}
|
||||
///设置插页总开关
|
||||
func setInterstitialSwitch(_ status:Bool) {
|
||||
interstitialSwitch = status
|
||||
}
|
||||
///获得插页开关的状态
|
||||
func getInterstitialSwitch() -> Bool {
|
||||
return interstitialSwitch
|
||||
}
|
||||
///开屏中介记录时间值
|
||||
private var intermediaryOpenShowTime:Date?
|
||||
///插页中介记录时间值
|
||||
private var intermediaryInterstitialShowTime:Date?
|
||||
///检索与插页广告之间的中介间隔时长是否达标
|
||||
private func retrieveIntermediaryInterstitial() -> Bool {
|
||||
//判断插页中介记录时间值是否存在
|
||||
guard let date = intermediaryInterstitialShowTime else {return true}
|
||||
return Date().timeIntervalSince(date) > intermediaryDuration
|
||||
}
|
||||
///检索与开屏广告之间的中介间隔时长是否达标
|
||||
private func retrieveIntermediaryOpen() -> Bool {
|
||||
//判断插页中介记录时间值是否存在
|
||||
guard let date = intermediaryOpenShowTime else {return true}
|
||||
return Date().timeIntervalSince(date) > intermediaryDuration
|
||||
}
|
||||
///是否达到插页间隔时长(达到即可继续展示插页广告)
|
||||
private func isShowInterstitialADAvailable(_ date:Date) -> Bool {
|
||||
return Date().timeIntervalSince(date) > interstitialDuration
|
||||
}
|
||||
override init() {
|
||||
super.init()
|
||||
reloadAppLovinIDs()
|
||||
//对开屏广告完成处理闭包
|
||||
completeOpenAdBlock = {
|
||||
[weak self] in
|
||||
guard let self = self, interstitialSwitch == true else {return}
|
||||
//销毁现在的开屏广告实例
|
||||
appOpenAd = nil
|
||||
isShowingOpenAd = false
|
||||
loadOpenAdTime = nil
|
||||
//关闭插页广告开关
|
||||
interstitialSwitch = false
|
||||
//更新开屏广告中介间隔时间
|
||||
intermediaryOpenShowTime = Date()
|
||||
//重新加载后续的开屏广告
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
|
||||
[weak self] in
|
||||
self?.loadOpenAd{ status in
|
||||
if status == true {
|
||||
print("新的开屏广告加载成功")
|
||||
}else {
|
||||
print("开屏广告加载失败了")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//搜索插页广告完成处理闭包
|
||||
completeSearchInterstitialAdBlock = {
|
||||
[weak self] in
|
||||
guard let self = self, interstitialSwitch == true else {return}
|
||||
//销毁现在的搜索插页广告实例
|
||||
searchInterstitialAd = nil
|
||||
isShowingSearchInterstitialAd = false
|
||||
loadSearchInterstitialAdTime = nil
|
||||
//关闭插页广告开关
|
||||
interstitialSwitch = false
|
||||
//更新插页广告中介间隔时长
|
||||
intermediaryInterstitialShowTime = Date()
|
||||
//重新加载后续的搜索插页广告
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
[weak self] in
|
||||
self?.loadSearchInterstitialAd { status in
|
||||
if status {
|
||||
print("成功加载搜索插页广告")
|
||||
}else {
|
||||
print("搜索插页广告加载失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//播放插页广告完成处理闭包
|
||||
completePlayInterstitialAdBlock = {
|
||||
[weak self] in
|
||||
guard let self = self, interstitialSwitch == true else {return}
|
||||
//销毁现在的播放插页广告实例
|
||||
playInterstitialAd = nil
|
||||
isShowingPlayInterstitialAd = false
|
||||
loadPlayInterstitialAdTime = nil
|
||||
//关闭插页广告开关
|
||||
interstitialSwitch = false
|
||||
//更新插页广告中介间隔时长
|
||||
intermediaryInterstitialShowTime = Date()
|
||||
//重新加载后续的播放插页广告
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
[weak self] in
|
||||
self?.loadPlayInterstitialAd { status in
|
||||
if status {
|
||||
print("成功加载播放插页广告")
|
||||
}else {
|
||||
print("播放插页广告加载失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//曲库插页广告完成处理闭包
|
||||
completeLibraryInterstitialAdBlock = {
|
||||
[weak self] in
|
||||
guard let self = self, interstitialSwitch == true else {return}
|
||||
//销毁现在的曲库插页广告实例
|
||||
libraryInterstitialAd = nil
|
||||
isShowingLibraryInterstitialAd = false
|
||||
loadLibraryInterstitialAdTime = nil
|
||||
//关闭插页广告开关
|
||||
interstitialSwitch = false
|
||||
//更新插页广告中介间隔时长
|
||||
intermediaryInterstitialShowTime = Date()
|
||||
//重新加载后续的曲库插页广告
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
[weak self] in
|
||||
self?.loadLibraryInterstitialAd { status in
|
||||
if status {
|
||||
print("成功加载曲库插页广告")
|
||||
}else {
|
||||
print("曲库插页广告加载失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
///初始化
|
||||
func startConfig() {
|
||||
//AppLovin初始化配置
|
||||
let initConfig = ALSdkInitializationConfiguration(sdkKey: SDKKey) { builder in
|
||||
builder.mediationProvider = ALMediationProviderMAX
|
||||
}
|
||||
//AppLovin初始化
|
||||
ALSdk.shared().initialize(with: initConfig) { sdkConfig in
|
||||
//开始加载AppLovin广告
|
||||
}
|
||||
//设置全部静音
|
||||
ALSdk.shared().settings.isMuted = true
|
||||
}
|
||||
///更新广告ID
|
||||
func reloadAppLovinIDs() {
|
||||
//更新要用到的广告信息
|
||||
if let data = UserDefaults.standard.object(forKey: "Max_OpenICEIDs") as? Data, let array = jsonforCoreAdModel(data) {
|
||||
print("成功提取ID")
|
||||
OpenIDs = array.sorted(by: {$0.level > $1.level})
|
||||
}
|
||||
if let data = UserDefaults.standard.object(forKey: "Max_SearchINSERTIDs") as? Data, let array = jsonforCoreAdModel(data) {
|
||||
SearchINSERTIDs = array.sorted(by: {$0.level > $1.level})
|
||||
}
|
||||
if let data = UserDefaults.standard.object(forKey: "Max_PlayerINSERTIDs") as? Data, let array = jsonforCoreAdModel(data) {
|
||||
PlayerINSERTIDs = array.sorted(by: {$0.level > $1.level})
|
||||
}
|
||||
if let data = UserDefaults.standard.object(forKey: "Max_LibraryNATIVEIDs") as? Data, let array = jsonforCoreAdModel(data) {
|
||||
LibraryINSERTIDs = array.sorted(by: {$0.level > $1.level})
|
||||
}
|
||||
}
|
||||
///加载广告
|
||||
func loadMoreAds(){
|
||||
loadPlayInterstitialAd{status in
|
||||
if status {
|
||||
print("成功加载播放插页广告")
|
||||
}else {
|
||||
print("播放插页广告加载失败")
|
||||
}
|
||||
}
|
||||
loadSearchInterstitialAd { status in
|
||||
if status {
|
||||
print("成功加载搜索插页广告")
|
||||
}else {
|
||||
print("搜索插页广告加载失败")
|
||||
}
|
||||
}
|
||||
loadLibraryInterstitialAd { status in
|
||||
if status {
|
||||
print("成功加载曲库插页广告")
|
||||
}else {
|
||||
print("曲库插页广告加载失败")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - 开屏广告
|
||||
///开屏广告ID组
|
||||
private var OpenIDs:[MPPositive_AdItemModel] = []
|
||||
///开屏广告
|
||||
var appOpenAd:MAInterstitialAd?
|
||||
///是否正在加载开屏广告
|
||||
private var isLoadingOpenAd:Bool = false
|
||||
///是否正在展示开屏广告
|
||||
var isShowingOpenAd:Bool = false
|
||||
//开屏广告加载时间
|
||||
private var loadOpenAdTime:Date?
|
||||
//开屏广告回调传值闭包
|
||||
private var loadStatuOpenAdBlock:((Bool) -> Void)?
|
||||
//开屏广告加载完成处理闭包
|
||||
var completeOpenAdBlock:(() -> Void)?
|
||||
//当前加载的ID数组Level阶级(从0开始,越低等级越高)
|
||||
private var openLevel:Int = 0
|
||||
//开屏广告时间间隔(默认10秒)
|
||||
private var openAppDuration:TimeInterval{
|
||||
get{
|
||||
if let times = UserDefaults.standard.object(forKey: "OpenAppDuration") as? TimeInterval {
|
||||
return times
|
||||
}else {
|
||||
return 10
|
||||
}
|
||||
}
|
||||
}
|
||||
//设置开屏广告时间间隔
|
||||
func setOpenAppDuration(_ duration:TimeInterval) {
|
||||
UserDefaults.standard.set(duration, forKey: "OpenAppDuration")
|
||||
}
|
||||
//获取开屏广告时间间隔
|
||||
func getOpenAppDuration() -> TimeInterval {
|
||||
return self.openAppDuration
|
||||
}
|
||||
///加载开屏广告
|
||||
func loadOpenAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
// 检测当前是否有广告或者有广告正在加载
|
||||
if isLoadingOpenAd || isOpenAdAvailable() {
|
||||
// 有广告或有广告在加载
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
//检索是否超过了对应的id组的阶级数量
|
||||
guard OpenIDs.isEmpty == false else {
|
||||
//冷启动无数据
|
||||
MP_AnalyticsManager.shared.max_lunch_showFailureAction("No IDs")
|
||||
//重新获取数据
|
||||
reloadAppLovinIDs()
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
guard level < (OpenIDs.count) else {
|
||||
print("开屏广告组已经全部加载失败,停止继续加载")
|
||||
MP_AnalyticsManager.shared.max_lunch_loadFailureAction("No Ads Fill")
|
||||
completion(false)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
||||
[weak self] in
|
||||
self?.loadOpenAd( completion: { status in
|
||||
if status {
|
||||
print("重新加载启动广告成功")
|
||||
}else {
|
||||
print("重新加载启动广告失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
let item = OpenIDs[level]
|
||||
openLevel = level
|
||||
//重置闭包导向
|
||||
loadStatuOpenAdBlock = completion
|
||||
//根据ID生成广告
|
||||
appOpenAd = MAInterstitialAd(adUnitIdentifier: item.identifier)
|
||||
appOpenAd?.delegate = self
|
||||
//加载开屏广告
|
||||
appOpenAd?.load()
|
||||
}
|
||||
///展示加载广告
|
||||
func showOpenAdIfAvailable(_ completion:((_ T:MAInterstitialAd) -> Void)?) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||||
guard !interstitialSwitch, !isShowingOpenAd, retrieveIntermediaryInterstitial() else { return }
|
||||
// 如果应用开屏广告尚不可用但应该显示,则加载新广告。
|
||||
if !isOpenAdAvailable() {
|
||||
loadOpenAd{ [weak self] success in
|
||||
guard let self = self else { return }
|
||||
if success {
|
||||
self.showOpenAdIfAvailable(completion)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.max_lunch_chanceAction()
|
||||
if let ad = appOpenAd, ad.isReady {
|
||||
//传递加载完成事件
|
||||
if let block = completion {
|
||||
block(ad)
|
||||
}else {
|
||||
isShowingOpenAd = true
|
||||
interstitialSwitch = true
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
//可以展示
|
||||
ad.show()
|
||||
}
|
||||
}
|
||||
}else {
|
||||
print("开屏广告展示失败")
|
||||
MP_AnalyticsManager.shared.max_lunch_showFailureAction("Ad loading failed")
|
||||
}
|
||||
}
|
||||
///查询是否有开屏广告
|
||||
func isOpenAdAvailable() -> Bool {
|
||||
return (appOpenAd != nil) && wasAdexpirationTime(loadOpenAdTime)
|
||||
}
|
||||
//MARK: - 搜索
|
||||
///搜索插页广告ID
|
||||
private var SearchINSERTIDs:[MPPositive_AdItemModel] = []
|
||||
///搜索插页广告
|
||||
private var searchInterstitialAd:MAInterstitialAd?
|
||||
///是否正在加载搜索插页广告
|
||||
private var isLoadingSearchInterstitialAd:Bool = false
|
||||
///是否正在展示搜索插页广告
|
||||
var isShowingSearchInterstitialAd:Bool = false
|
||||
///搜索插页加载时间
|
||||
private var loadSearchInterstitialAdTime:Date?
|
||||
///搜索广告处理闭包
|
||||
var completeSearchInterstitialAdBlock:(() -> Void)?
|
||||
//开屏广告回调传值闭包
|
||||
private var loadStatuSearchAdBlock:((Bool) -> Void)?
|
||||
//当前加载的ID数组Level阶级(从0开始,越低等级越高)
|
||||
private var searchLevel:Int = 0
|
||||
//异步加载搜索插页广告
|
||||
func loadSearchInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
if isLoadingSearchInterstitialAd || isSearchInterstitialAdAvailable() {
|
||||
// 有广告或有广告在加载
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
guard SearchINSERTIDs.isEmpty == false else {
|
||||
MP_AnalyticsManager.shared.max_search_showFailureAction("No IDs")
|
||||
//重新获取数据
|
||||
reloadAppLovinIDs()
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
guard level < (SearchINSERTIDs.count) else {
|
||||
print("搜索插页广告组已经全部加载失败,停止继续加载")
|
||||
MP_AnalyticsManager.shared.max_search_loadFailureAction("No Ads Fill")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
[weak self] in
|
||||
self?.loadSearchInterstitialAd { status in
|
||||
if status {
|
||||
print("重新加载搜索插页广告")
|
||||
}else {
|
||||
print("加载搜索插页广告失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
isLoadingSearchInterstitialAd = true
|
||||
searchLevel = level
|
||||
//重置闭包导向
|
||||
loadStatuSearchAdBlock = completion
|
||||
let item = SearchINSERTIDs[level]
|
||||
//根据ID生成广告
|
||||
searchInterstitialAd = MAInterstitialAd(adUnitIdentifier: item.identifier)
|
||||
searchInterstitialAd?.delegate = self
|
||||
//加载开屏广告
|
||||
searchInterstitialAd?.load()
|
||||
}
|
||||
///搜索插页广告展示
|
||||
func showSearchInterstitialAdIfAvailable(_ completion:((MAInterstitialAd) -> Void)?) {
|
||||
guard openAdStatus, internalAdStatus else {return}
|
||||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||||
guard !interstitialSwitch, !isShowingSearchInterstitialAd, retrieveIntermediaryOpen() else { return }
|
||||
//检索是否存在插页间隔时间
|
||||
if let date = interstitialDate {
|
||||
if isShowInterstitialADAvailable(date) == false {
|
||||
//未超过插页间隔时长
|
||||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||||
return
|
||||
}
|
||||
}
|
||||
// 如果搜索广告尚不可用但应该显示,则加载新广告。
|
||||
if !isSearchInterstitialAdAvailable() {
|
||||
loadSearchInterstitialAd { [weak self] success in
|
||||
guard let self = self else { return }
|
||||
if success {
|
||||
self.showSearchInterstitialAdIfAvailable(completion)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.max_search_chanceAction()
|
||||
//当搜索插页广告确定有值后展示
|
||||
if let ad = searchInterstitialAd, ad.isReady {
|
||||
//传递加载完成事件
|
||||
if let block = completion {
|
||||
block(ad)
|
||||
}else {
|
||||
isShowingSearchInterstitialAd = true
|
||||
interstitialSwitch = true
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
//可以展示
|
||||
ad.show()
|
||||
}
|
||||
}
|
||||
}else {
|
||||
MP_AnalyticsManager.shared.max_search_showFailureAction("Ad loading failed")
|
||||
}
|
||||
}
|
||||
//查询是否有搜索插页广告
|
||||
func isSearchInterstitialAdAvailable() -> Bool {
|
||||
return searchInterstitialAd != nil && wasAdexpirationTime(loadSearchInterstitialAdTime)
|
||||
}
|
||||
//MARK: - 播放/切割插页广告位
|
||||
///播放插页广告ID
|
||||
private var PlayerINSERTIDs:[MPPositive_AdItemModel] = []
|
||||
///播放插页广告
|
||||
var playInterstitialAd:MAInterstitialAd?
|
||||
///是否正在加载播放插页广告
|
||||
private var isLoadingPlayInterstitialAd:Bool = false
|
||||
///是否正在展示播放插页广告
|
||||
var isShowingPlayInterstitialAd:Bool = false
|
||||
///播放插页加载时间
|
||||
private var loadPlayInterstitialAdTime:Date?
|
||||
///播放广告处理闭包
|
||||
var completePlayInterstitialAdBlock:(() -> Void)?
|
||||
//开屏广告回调传值闭包
|
||||
private var loadStatuPlayAdBlock:((Bool) -> Void)?
|
||||
//当前加载的ID数组Level阶级(从0开始,越低等级越高)
|
||||
private var playLevel:Int = 0
|
||||
//异步加载播放插页广告
|
||||
func loadPlayInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||||
guard openAdStatus, internalAdStatus else {
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
// 检测当前是否有广告或者有广告正在加载
|
||||
if isLoadingPlayInterstitialAd || isPlayInterstitialAdAvailable() {
|
||||
// 有广告或有广告在加载
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
guard PlayerINSERTIDs.isEmpty == false else {
|
||||
MP_AnalyticsManager.shared.max_play_showFailureAction("No IDs")
|
||||
//重新获取数据
|
||||
reloadAppLovinIDs()
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
|
||||
guard level < (PlayerINSERTIDs.count) else {
|
||||
print("播放插页广告组已经全部加载失败,停止继续加载")
|
||||
MP_AnalyticsManager.shared.max_play_loadFailureAction("No Ads Fill")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
[weak self] in
|
||||
self?.loadPlayInterstitialAd { status in
|
||||
if status {
|
||||
print("重新加载播放插页广告")
|
||||
}else {
|
||||
print("加载播放插页广告失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
isLoadingPlayInterstitialAd = true
|
||||
playLevel = level
|
||||
//重置闭包导向
|
||||
loadStatuPlayAdBlock = completion
|
||||
let item = PlayerINSERTIDs[level]
|
||||
//根据ID生成广告
|
||||
playInterstitialAd = MAInterstitialAd(adUnitIdentifier: item.identifier)
|
||||
playInterstitialAd?.delegate = self
|
||||
//加载开屏广告
|
||||
playInterstitialAd?.load()
|
||||
}
|
||||
///播放插页广告展示
|
||||
func showPlayInterstitialAdIfAvailable(_ completion:((MAInterstitialAd?) -> Void)?) {
|
||||
guard openAdStatus, internalAdStatus else {
|
||||
completion?(nil)
|
||||
return
|
||||
}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
completion?(nil)
|
||||
return
|
||||
}
|
||||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||||
guard !interstitialSwitch, !isShowingPlayInterstitialAd, retrieveIntermediaryOpen() else {
|
||||
completion?(nil)
|
||||
return
|
||||
}
|
||||
//检索是否存在插页间隔时间
|
||||
if let date = interstitialDate {
|
||||
if isShowInterstitialADAvailable(date) == false {
|
||||
//未超过插页间隔时长
|
||||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||||
completion?(nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
// 如果播放插页广告尚不可用但应该显示,则加载新广告。
|
||||
if !isPlayInterstitialAdAvailable() {
|
||||
loadPlayInterstitialAd{ [weak self] success in
|
||||
guard let self = self else { return }
|
||||
if success {
|
||||
print("播放广告已加载")
|
||||
}
|
||||
}
|
||||
completion?(nil)
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.max_play_chanceACtion()
|
||||
//当播放插页广告确定有值后展示
|
||||
if let ad = playInterstitialAd, ad.isReady {
|
||||
//传递加载完成事件
|
||||
if let block = completion {
|
||||
block(ad)
|
||||
}else {
|
||||
isShowingPlayInterstitialAd = true
|
||||
interstitialSwitch = true
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
//可以展示
|
||||
ad.show()
|
||||
}
|
||||
}
|
||||
}else {
|
||||
MP_AnalyticsManager.shared.max_play_showFailureAction("Ad loading failed")
|
||||
completion?(nil)
|
||||
}
|
||||
}
|
||||
//查询是否有播放插页广告
|
||||
func isPlayInterstitialAdAvailable() -> Bool {
|
||||
return playInterstitialAd != nil && wasAdexpirationTime(loadPlayInterstitialAdTime)
|
||||
}
|
||||
//MARK: - 曲库/下载插页广告位
|
||||
///曲库插页ID
|
||||
private var LibraryINSERTIDs:[MPPositive_AdItemModel] = []
|
||||
///曲库插页广告
|
||||
private var libraryInterstitialAd:MAInterstitialAd?
|
||||
///是否正在加载曲库插页广告
|
||||
private var isLoadingLibraryInterstitialAd:Bool = false
|
||||
///是否正在展示曲库插页广告
|
||||
var isShowingLibraryInterstitialAd:Bool = false
|
||||
///曲库插页加载时间
|
||||
private var loadLibraryInterstitialAdTime:Date?
|
||||
///曲库广告处理闭包
|
||||
var completeLibraryInterstitialAdBlock:(() -> Void)?
|
||||
//开屏广告回调传值闭包
|
||||
private var loadStatuLibraryAdBlock:((Bool) -> Void)?
|
||||
//当前加载的ID数组Level阶级(从0开始,越低等级越高)
|
||||
private var libraryLevel:Int = 0
|
||||
//异步加载曲库插页广告
|
||||
func loadLibraryInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||||
guard openAdStatus, internalAdStatus else {
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
// 检测当前是否有广告或者有广告正在加载
|
||||
if isLoadingLibraryInterstitialAd || isLibraryInterstitialAdAvailable() {
|
||||
// 有广告或有广告在加载
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
guard LibraryINSERTIDs.isEmpty == false else {
|
||||
MP_AnalyticsManager.shared.max_library_showFailureAction("No IDs")
|
||||
//重新获取数据
|
||||
reloadAppLovinIDs()
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
guard level < (LibraryINSERTIDs.count) else {
|
||||
print("曲库插页广告组已经全部加载失败,停止继续加载")
|
||||
MP_AnalyticsManager.shared.max_library_loadFailureAction("No Ads Fill")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
[weak self] in
|
||||
self?.loadLibraryInterstitialAd { status in
|
||||
if status {
|
||||
print("重新加载曲库插页广告")
|
||||
}else {
|
||||
print("加载曲库插页广告失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
isLoadingLibraryInterstitialAd = true
|
||||
libraryLevel = level
|
||||
//重置闭包导向
|
||||
loadStatuLibraryAdBlock = completion
|
||||
let item = LibraryINSERTIDs[level]
|
||||
//根据ID生成广告
|
||||
libraryInterstitialAd = MAInterstitialAd(adUnitIdentifier: item.identifier)
|
||||
libraryInterstitialAd?.delegate = self
|
||||
//加载开屏广告
|
||||
libraryInterstitialAd?.load()
|
||||
}
|
||||
///曲库插页广告展示
|
||||
func showLibraryInterstitialAdIfAvailable(_ completion:((MAInterstitialAd) -> Void)?) {
|
||||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||||
guard !interstitialSwitch, !isShowingLibraryInterstitialAd, retrieveIntermediaryOpen() else { return }
|
||||
//检索是否存在插页间隔时间
|
||||
if let date = interstitialDate {
|
||||
if isShowInterstitialADAvailable(date) == false {
|
||||
//未超过插页间隔时长
|
||||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||||
return
|
||||
}
|
||||
}
|
||||
// 如果曲库广告尚不可用但应该显示,则加载新广告。
|
||||
if !isLibraryInterstitialAdAvailable() {
|
||||
loadLibraryInterstitialAd { [weak self] success in
|
||||
guard let self = self else { return }
|
||||
if success {
|
||||
self.showLibraryInterstitialAdIfAvailable(completion)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.max_library_chanceAction()
|
||||
//当曲库插页广告确定有值后展示
|
||||
if let ad = libraryInterstitialAd, ad.isReady {
|
||||
//传递加载完成事件
|
||||
if let block = completion {
|
||||
block(ad)
|
||||
}else {
|
||||
isShowingPlayInterstitialAd = true
|
||||
interstitialSwitch = true
|
||||
DispatchQueue.main.async {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
//可以展示
|
||||
ad.show()
|
||||
}
|
||||
}
|
||||
}else {
|
||||
MP_AnalyticsManager.shared.max_library_showFailureAction("Ad loading failed")
|
||||
}
|
||||
}
|
||||
//查询是否有曲库插页广告
|
||||
func isLibraryInterstitialAdAvailable() -> Bool {
|
||||
return libraryInterstitialAd != nil && wasAdexpirationTime(loadLibraryInterstitialAdTime)
|
||||
}
|
||||
}
|
||||
//MARK: - 插页广告代理实现
|
||||
extension MP_AppLovinManager: MAAdDelegate {
|
||||
//广告加载成功
|
||||
func didLoad(_ ad: MAAd) {
|
||||
let adUnitIdentifier = ad.adUnitIdentifier
|
||||
//判断广告位
|
||||
if adUnitIdentifier == appOpenAd?.adUnitIdentifier {
|
||||
//是开屏广告,调整加载状态
|
||||
isLoadingOpenAd = false
|
||||
//更新开屏广告加载时间
|
||||
loadOpenAdTime = Date()
|
||||
//实现开屏广告回调闭包
|
||||
if let block = loadStatuOpenAdBlock {
|
||||
block(true)
|
||||
}
|
||||
}else if adUnitIdentifier == searchInterstitialAd?.adUnitIdentifier {
|
||||
//是搜索插页广告,调整加载状态
|
||||
isLoadingSearchInterstitialAd = false
|
||||
//更新搜索插页广告加载时间
|
||||
loadSearchInterstitialAdTime = Date()
|
||||
//实现搜索插页广告回调闭包
|
||||
if let block = loadStatuSearchAdBlock {
|
||||
block(true)
|
||||
}
|
||||
}else if adUnitIdentifier == playInterstitialAd?.adUnitIdentifier {
|
||||
//是播放插页广告
|
||||
isLoadingPlayInterstitialAd = false
|
||||
//更新播放插页广告加载时间
|
||||
loadPlayInterstitialAdTime = Date()
|
||||
//实现播放插页广告回调闭包
|
||||
if let block = loadStatuPlayAdBlock {
|
||||
block(true)
|
||||
}
|
||||
}else if adUnitIdentifier == libraryInterstitialAd?.adUnitIdentifier {
|
||||
//是曲库插页广告
|
||||
isLoadingLibraryInterstitialAd = false
|
||||
//更新曲库插页广告加载时间
|
||||
loadLibraryInterstitialAdTime = Date()
|
||||
//实现曲库插页广告回调
|
||||
if let block = loadStatuLibraryAdBlock {
|
||||
block(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
//广告加载失败
|
||||
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
|
||||
//判断广告位
|
||||
if adUnitIdentifier == appOpenAd?.adUnitIdentifier {
|
||||
//是开屏广告,调整加载状态
|
||||
isLoadingOpenAd = false
|
||||
//开屏广告加载失败,销毁广告
|
||||
appOpenAd = nil
|
||||
MP_AnalyticsManager.shared.max_lunch_loadFailureAction(error.message)
|
||||
if let block = loadStatuOpenAdBlock {
|
||||
//重新加载广告
|
||||
loadOpenAd(openLevel + 1, completion: block)
|
||||
}
|
||||
}else if adUnitIdentifier == searchInterstitialAd?.adUnitIdentifier {
|
||||
//是搜索插页广告,调整加载状态
|
||||
isLoadingSearchInterstitialAd = false
|
||||
searchInterstitialAd = nil
|
||||
MP_AnalyticsManager.shared.max_search_loadFailureAction(error.message)
|
||||
if let block = loadStatuSearchAdBlock {
|
||||
loadSearchInterstitialAd(searchLevel + 1, completion: block)
|
||||
}
|
||||
}else if adUnitIdentifier == playInterstitialAd?.adUnitIdentifier {
|
||||
//是播放插页广告
|
||||
isLoadingPlayInterstitialAd = false
|
||||
playInterstitialAd = nil
|
||||
MP_AnalyticsManager.shared.max_play_loadFailureAction(error.message)
|
||||
if let block = loadStatuPlayAdBlock {
|
||||
loadPlayInterstitialAd(playLevel + 1, completion: block)
|
||||
}
|
||||
}else if adUnitIdentifier == libraryInterstitialAd?.adUnitIdentifier {
|
||||
//是曲库插页广告
|
||||
isLoadingLibraryInterstitialAd = false
|
||||
libraryInterstitialAd = nil
|
||||
MP_AnalyticsManager.shared.max_library_loadFailureAction(error.message)
|
||||
if let block = loadStatuLibraryAdBlock {
|
||||
loadLibraryInterstitialAd(libraryLevel + 1, completion: block)
|
||||
}
|
||||
}
|
||||
}
|
||||
//广告展示
|
||||
func didDisplay(_ ad: MAAd) {
|
||||
let adUnitIdentifier = ad.adUnitIdentifier
|
||||
//检索广告位
|
||||
if adUnitIdentifier == appOpenAd?.adUnitIdentifier {
|
||||
//开屏广告
|
||||
print("当前展示的广告是开屏广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
//上传广告事件
|
||||
}else if adUnitIdentifier == searchInterstitialAd?.adUnitIdentifier {
|
||||
//搜索广告位
|
||||
print("当前展示的广告是搜索插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
//上传广告事件
|
||||
}else if adUnitIdentifier == playInterstitialAd?.adUnitIdentifier {
|
||||
//播放广告位
|
||||
print("当前展示的广告是播放插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
}else if adUnitIdentifier == libraryInterstitialAd?.adUnitIdentifier {
|
||||
//曲库广告位
|
||||
print("当前展示的广告是曲库插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
}
|
||||
}
|
||||
//广告关闭
|
||||
func didHide(_ ad: MAAd) {
|
||||
let adUnitIdentifier = ad.adUnitIdentifier
|
||||
//更新插页广告展示时间
|
||||
interstitialDate = Date()
|
||||
if adUnitIdentifier == appOpenAd?.adUnitIdentifier {
|
||||
print("当前消失的广告是开屏广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
if let block = completeOpenAdBlock {
|
||||
block()
|
||||
}
|
||||
}else if adUnitIdentifier == searchInterstitialAd?.adUnitIdentifier {
|
||||
//搜索广告位
|
||||
print("当前消失的广告是搜索插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
if let block = completeSearchInterstitialAdBlock {
|
||||
block()
|
||||
}
|
||||
}else if adUnitIdentifier == playInterstitialAd?.adUnitIdentifier {
|
||||
//播放广告位
|
||||
print("当前消失的广告是播放插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
if let block = completePlayInterstitialAdBlock {
|
||||
block()
|
||||
}
|
||||
}else if adUnitIdentifier == libraryInterstitialAd?.adUnitIdentifier {
|
||||
//曲库广告位
|
||||
print("当前消失的广告是曲库插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
if let block = completeLibraryInterstitialAdBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
//广告点击
|
||||
func didClick(_ ad: MAAd) {
|
||||
|
||||
}
|
||||
//广告展示失败
|
||||
func didFail(toDisplay ad: MAAd, withError error: MAError) {
|
||||
let adUnitIdentifier = ad.adUnitIdentifier
|
||||
//更新插页广告展示时间
|
||||
interstitialDate = Date()
|
||||
if adUnitIdentifier == appOpenAd?.adUnitIdentifier {
|
||||
print("开屏广告展示时出错,广告ID--\(ad.adUnitIdentifier),具体错误原因:\(error.message)")
|
||||
MP_AnalyticsManager.shared.max_lunch_showFailureAction(error.message)
|
||||
if let block = completeOpenAdBlock {
|
||||
block()
|
||||
}
|
||||
}else if adUnitIdentifier == searchInterstitialAd?.adUnitIdentifier {
|
||||
//搜索广告位
|
||||
print("搜索插页广告展示时出错,广告ID--\(ad.adUnitIdentifier),具体错误原因:\(error.message)")
|
||||
MP_AnalyticsManager.shared.max_search_showFailureAction(error.message)
|
||||
if let block = completeSearchInterstitialAdBlock {
|
||||
block()
|
||||
}
|
||||
}else if adUnitIdentifier == playInterstitialAd?.adUnitIdentifier {
|
||||
//播放广告位
|
||||
print("播放插页广告展示时出错,广告ID--\(ad.adUnitIdentifier),具体错误原因:\(error.message)")
|
||||
MP_AnalyticsManager.shared.max_play_showFailureAction(error.message)
|
||||
if let block = completePlayInterstitialAdBlock {
|
||||
block()
|
||||
}
|
||||
}else if adUnitIdentifier == libraryInterstitialAd?.adUnitIdentifier {
|
||||
//曲库广告位
|
||||
print("曲库插页广告展示时出错,广告ID--\(ad.adUnitIdentifier),具体错误原因:\(error.message)")
|
||||
MP_AnalyticsManager.shared.max_library_showFailureAction(error.message)
|
||||
if let block = completeLibraryInterstitialAdBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -114,6 +114,8 @@ class MP_DownloadManager: NSObject {
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
}failure: { statu in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
|
||||
@ -31,7 +31,7 @@ class MP_HUD: NSObject {
|
||||
SVProgressHUD.setBackgroundColor(.init(hex: "#80F988", alpha: 0.15))
|
||||
SVProgressHUD.setForegroundColor(.init(hex: "#80F988"))
|
||||
SVProgressHUD.setOffsetFromCenter(.init(horizontal: 0, vertical: 0))
|
||||
if MP_AdMobManager.shared.getInterstitialSwitch() {
|
||||
if MP_ADSimpleManager.shared.getInterstitialSwitch() {
|
||||
//当前正在展示插页
|
||||
|
||||
}else {
|
||||
@ -46,7 +46,7 @@ class MP_HUD: NSObject {
|
||||
SVProgressHUD.setBackgroundColor(.init(hex: "#80F988", alpha: 0.15))
|
||||
SVProgressHUD.setForegroundColor(.init(hex: "#80F988"))
|
||||
SVProgressHUD.setOffsetFromCenter(.init(horizontal: 0, vertical: 0))
|
||||
if MP_AdMobManager.shared.getInterstitialSwitch() {
|
||||
if MP_ADSimpleManager.shared.getInterstitialSwitch() {
|
||||
//当前正在展示插页
|
||||
guard let completion = completion else{
|
||||
return
|
||||
@ -104,7 +104,7 @@ class MP_HUD: NSObject {
|
||||
SVProgressHUD.setBackgroundColor(.init(hex: "#80F988", alpha: 0.15))
|
||||
SVProgressHUD.setForegroundColor(.init(hex: "#80F988"))
|
||||
SVProgressHUD.setOffsetFromCenter(.init(horizontal: 0, vertical: 0))
|
||||
if MP_AdMobManager.shared.getInterstitialSwitch() {
|
||||
if MP_ADSimpleManager.shared.getInterstitialSwitch() {
|
||||
//当前正在展示插页
|
||||
guard let completion = completion else{
|
||||
return
|
||||
|
||||
@ -76,7 +76,7 @@ class MP_IAPManager: NSObject {
|
||||
// 收据不存在
|
||||
print("没有收据,广告默认开")
|
||||
//不能调用AppStore,默认使用广告
|
||||
MP_AdMobManager.shared.setOpenAdStatus(true)
|
||||
MP_ADSimpleManager.shared.setOpenAdStatus(true)
|
||||
return
|
||||
}
|
||||
//收据,重置交易记录
|
||||
@ -90,7 +90,7 @@ class MP_IAPManager: NSObject {
|
||||
// 收据不存在
|
||||
print("没有收据,广告默认开")
|
||||
//不能调用AppStore,默认使用广告
|
||||
MP_AdMobManager.shared.setOpenAdStatus(true)
|
||||
MP_ADSimpleManager.shared.setOpenAdStatus(true)
|
||||
return
|
||||
}
|
||||
//有收据
|
||||
@ -102,9 +102,9 @@ class MP_IAPManager: NSObject {
|
||||
//更新广告开关状态
|
||||
if isProductPurchased(productId: productIdentifiers[0]) || isProductPurchased(productId: productIdentifiers[1]) || isProductPurchased(productId: productIdentifiers[2]){
|
||||
//设置广告开关为关
|
||||
MP_AdMobManager.shared.setOpenAdStatus(false)
|
||||
MP_ADSimpleManager.shared.setOpenAdStatus(false)
|
||||
}else {
|
||||
MP_AdMobManager.shared.setOpenAdStatus(true)
|
||||
MP_ADSimpleManager.shared.setOpenAdStatus(true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ extension MP_IAPManager: SKProductsRequestDelegate, SKPaymentTransactionObserver
|
||||
productIdentifiers.forEach { item in
|
||||
cleanPurchase(productId: item)
|
||||
}
|
||||
MP_AdMobManager.shared.setOpenAdStatus(true)
|
||||
MP_ADSimpleManager.shared.setOpenAdStatus(true)
|
||||
}
|
||||
}
|
||||
func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: any Error) {
|
||||
@ -172,7 +172,7 @@ extension MP_IAPManager: SKProductsRequestDelegate, SKPaymentTransactionObserver
|
||||
productIdentifiers.forEach { item in
|
||||
cleanPurchase(productId: item)
|
||||
}
|
||||
MP_AdMobManager.shared.setOpenAdStatus(true)
|
||||
MP_ADSimpleManager.shared.setOpenAdStatus(true)
|
||||
}
|
||||
//存入交易信息值
|
||||
private func storePurchase(productId: String) {
|
||||
|
||||
@ -9,6 +9,7 @@ import UIKit
|
||||
import Alamofire
|
||||
import Security
|
||||
import AdSupport
|
||||
|
||||
///自家后台管理器
|
||||
class MP_LuxServerManager: NSObject {
|
||||
//单例工具
|
||||
@ -60,7 +61,7 @@ class MP_LuxServerManager: NSObject {
|
||||
}
|
||||
/// 设备类型
|
||||
private var deviceVersion: String {
|
||||
return UIDevice.current.name
|
||||
return UIDevice.current.modelName
|
||||
}
|
||||
///系统版本
|
||||
private var osVersion:String {
|
||||
|
||||
@ -973,7 +973,7 @@ extension MP_NetWorkManager {
|
||||
//MARK: - 请求player播放资源
|
||||
/// 请求Player(单曲/视频)播放资源
|
||||
/// - Parameter item: 请求的预览实体
|
||||
func requestAndroidPlayer(_ videoId: String, playlistId: String, clickTrackingParams: String?, completion:@escaping ((([String],[Int],[String])?, [String]?) -> Void)){
|
||||
func requestAndroidPlayer(_ videoId: String, playlistId: String, clickTrackingParams: String?, completion:@escaping ((([String],[Int],[String])?, [String]?) -> Void), failure: ((Bool) -> Void)? = nil){
|
||||
guard netWorkStatu != .notReachable else {
|
||||
completion(nil,nil)
|
||||
return
|
||||
@ -1006,9 +1006,11 @@ extension MP_NetWorkManager {
|
||||
//guard netWorkStatu != .notReachable else {return}
|
||||
requestAndroidPostPlayer(url, videoId: videoId, parameters: parameters){ resourceUlrs, coverUrls in
|
||||
completion(resourceUlrs, coverUrls)
|
||||
} failure: { statu in
|
||||
failure?(statu)
|
||||
}
|
||||
}
|
||||
private func requestAndroidPostPlayer(_ url:URL, videoId:String, parameters:Parameters, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void)) {
|
||||
private func requestAndroidPostPlayer(_ url:URL, videoId:String, parameters:Parameters, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void), failure:((Bool) -> Void)? = nil) {
|
||||
//发送post请求
|
||||
let request = PlayerSeesion.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonAndroidPlayer.self) { [weak self] (response) in
|
||||
guard let self = self else {return}
|
||||
@ -1016,11 +1018,16 @@ extension MP_NetWorkManager {
|
||||
switch response.result {
|
||||
case .success(let value):
|
||||
parsingAndroidPlayer(value) { resourceUlrs, coverUrls in
|
||||
//成功获得资源
|
||||
completion(resourceUlrs, coverUrls)
|
||||
} failure: { statu in
|
||||
//失败
|
||||
failure?(statu)
|
||||
}
|
||||
|
||||
case .failure(let error):
|
||||
//当前无数据
|
||||
completion(nil,nil)
|
||||
failure?(false)
|
||||
// 请求失败,处理错误
|
||||
handleError(url, error: error, status: false)
|
||||
}
|
||||
@ -2034,17 +2041,20 @@ extension MP_NetWorkManager {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
private func parsingAndroidPlayer(_ player:JsonAndroidPlayer,completion:@escaping((([String],[Int],[String]), [String]?) -> Void)){
|
||||
private func parsingAndroidPlayer(_ player:JsonAndroidPlayer,completion:@escaping((([String],[Int],[String]), [String]?) -> Void), failure:((Bool) -> Void)? = nil){
|
||||
var infos:[String]?
|
||||
//解析player,获取资源库和信息库
|
||||
if let videoDetails = player.videoDetails {
|
||||
infos = parsingAndroidPlayerVideoDetails(videoDetails)
|
||||
}
|
||||
if let streamingData = player.streamingData {
|
||||
//存在资源
|
||||
parsingAndroidPlayerStreamingData(streamingData){ videos,itags,mimeType in
|
||||
completion((videos,itags,mimeType),infos)
|
||||
}
|
||||
}else {
|
||||
//不存在资源(通常是IP被拉黑了)
|
||||
failure?(true)
|
||||
MP_HUD.error("Failed to obtain resource, please try again later", delay: 1.0, completion: nil)
|
||||
MP_AnalyticsManager.shared.player_resource_failureAction(locaton ?? "HK")
|
||||
}
|
||||
|
||||
@ -232,6 +232,8 @@ class MP_PlayerManager:NSObject{
|
||||
private var playbackLikelyToKeepUpObservation:NSKeyValueObservation?
|
||||
///播放实例报错的监听器
|
||||
private var errorObservation:NSKeyValueObservation?
|
||||
///播放实例播放资格监听器
|
||||
private var playEntitlementObservation:NSKeyValueObservation?
|
||||
private override init() {
|
||||
super.init()
|
||||
//初始化计时器
|
||||
@ -314,6 +316,14 @@ class MP_PlayerManager:NSObject{
|
||||
if startAction != nil {
|
||||
startActionBlock = startAction
|
||||
}
|
||||
//检索是否具备播放资格
|
||||
guard loadPlayer?.currentVideo?.isPlayEntitlement != false else {
|
||||
//明确不可播放, 执行下一首
|
||||
if MP_NetWorkManager.shared.netWorkStatu == .reachable {
|
||||
nextEvent()
|
||||
}
|
||||
return
|
||||
}
|
||||
if let currentVideo = loadPlayer?.currentVideo {
|
||||
//覆盖播放器原有的playerItem
|
||||
player.replaceCurrentItem(with: currentVideo.resourcePlayerItem)
|
||||
@ -412,6 +422,15 @@ class MP_PlayerManager:NSObject{
|
||||
MP_AnalyticsManager.shared.player_b_failure_errorAction(currentVideo.song.videoId ?? "", videoname: currentVideo.title ?? "", artistname: currentVideo.song.shortBylineText ?? "", error: nsError.localizedDescription)
|
||||
}
|
||||
})
|
||||
//播放资格
|
||||
playEntitlementObservation?.invalidate()
|
||||
playEntitlementObservation = currentVideo.observe(\.isPlayEntitlement, options: [.old,.new], changeHandler: { [weak self] item, change in
|
||||
guard let self = self, MP_NetWorkManager.shared.netWorkStatu == .reachable else {return}
|
||||
if change.newValue == 0 {
|
||||
//当前音乐不具备播放资格,直接下一首
|
||||
nextEvent()
|
||||
}
|
||||
})
|
||||
currentVideo.isKVO = true
|
||||
//将进度回归为0
|
||||
player.seek(to: .zero)
|
||||
@ -485,7 +504,17 @@ class MP_PlayerManager:NSObject{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//确定播放器播放后限时状态
|
||||
func playerStatuTimerAction() {
|
||||
MPPositive_Debouncer.shared.playCall {
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
//10秒后检索播放器是否在播放
|
||||
if playState != .Playing {
|
||||
MP_HUD.text("Failed to obtain resource, please try again later".localizableString(), delay: 2.0, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
//获取缓冲值
|
||||
private func cacheLoadTimes() {
|
||||
//获取当前播放Item的缓冲值组
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// MPPositive_AdModelModel.swift
|
||||
// MPPositive_AdItemModel.swift
|
||||
// relax.offline.mp3.music
|
||||
//
|
||||
// Created by Mr.Zhou on 2024/7/10.
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
import UIKit
|
||||
///广告模型
|
||||
class MPPositive_AdModelModel: NSObject, Codable {
|
||||
class MPPositive_AdItemModel: NSObject, Codable {
|
||||
///阶级(从高到低)
|
||||
var level:Int
|
||||
///id内容
|
||||
@ -16,12 +16,15 @@ class MPPositive_LibraryItemModel: NSObject {
|
||||
var title:String
|
||||
///唯一标识符
|
||||
var identifier:String?
|
||||
///数量组
|
||||
var count:Int
|
||||
|
||||
init(libraryType: LibraryType, coverUrl: URL?, title: String, identifier: String? = nil) {
|
||||
init(libraryType: LibraryType, coverUrl: URL?, title: String, identifier: String? = nil, count:Int) {
|
||||
self.libraryType = libraryType
|
||||
self.coverUrl = coverUrl
|
||||
self.title = title
|
||||
self.identifier = identifier
|
||||
self.count = count
|
||||
}
|
||||
}
|
||||
///Library指向类型
|
||||
|
||||
@ -56,30 +56,30 @@ class MPPositive_LibraryListViewModel: NSObject {
|
||||
}
|
||||
if songs.isEmpty == false, let lastUrl = songs.first?.coverURL {
|
||||
//获取收藏歌曲
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_songs, coverUrl: lastUrl, title: "Love Songs".localizableString()))
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_songs, coverUrl: lastUrl, title: "Love Songs".localizableString(), count: songs.count))
|
||||
array.append(item)
|
||||
}else {
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_songs, coverUrl: nil, title: "Love Songs".localizableString()))
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_songs, coverUrl: nil, title: "Love Songs".localizableString(), count: 0))
|
||||
array.append(item)
|
||||
}
|
||||
if artists.isEmpty == false, let lastUrl = artists.first?.coverURL {
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_aritists, coverUrl: lastUrl, title: "Love Artists".localizableString()))
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_aritists, coverUrl: lastUrl, title: "Love Artists".localizableString(), count: artists.count))
|
||||
array.append(item)
|
||||
}else {
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_aritists, coverUrl: nil, title: "Love Artists".localizableString()))
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .love_aritists, coverUrl: nil, title: "Love Artists".localizableString(), count: 0))
|
||||
array.append(item)
|
||||
}
|
||||
if offlines.isEmpty == false, let lastUrl = offlines.first?.reviewURL {
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .offline_songs, coverUrl: lastUrl, title: "Offline Songs".localizableString()))
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .offline_songs, coverUrl: lastUrl, title: "Offline Songs".localizableString(), count: offlines.count))
|
||||
array.append(item)
|
||||
}else {
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .offline_songs, coverUrl: nil, title: "Offline Songs".localizableString()))
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .offline_songs, coverUrl: nil, title: "Offline Songs".localizableString(), count: 0))
|
||||
array.append(item)
|
||||
}
|
||||
//对自定义列表进行添加
|
||||
MPPositive_LoadCoreModel.shared.playLists.forEach { list in
|
||||
if list.playList.videosArray.isEmpty == false, let lastUrl = list.coverImageURL, let title = list.title, let identifier = list.playList.playListId {
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .custom_playlist, coverUrl: lastUrl, title: title, identifier: identifier))
|
||||
let item = MPPositive_LibraryViewModel(.init(libraryType: .custom_playlist, coverUrl: lastUrl, title: title, identifier: identifier, count: 0))
|
||||
array.append(item)
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ class MPPositive_SongViewModel: NSObject {
|
||||
var isKVO:Bool = false
|
||||
///是否完成了预加载
|
||||
var isPreload:Bool = false
|
||||
///是否无数据
|
||||
var isEmptyResource:Bool = false
|
||||
///是否可以播放(会因为各种问题导致这首歌并不能播放)
|
||||
@objc dynamic var isPlayEntitlement:NSNumber?
|
||||
|
||||
///音乐实体
|
||||
var song:MPPositive_SongItemModel!
|
||||
init(_ song:MPPositive_SongItemModel) {
|
||||
@ -80,7 +85,10 @@ class MPPositive_SongViewModel: NSObject {
|
||||
if song.lyricsID == nil || song.relatedID == nil {
|
||||
//需要网络请求补全数据
|
||||
improveDataforLycirsAndRelated(song) {[weak self] (result) in
|
||||
guard let self = self else {return}
|
||||
guard let self = self else {
|
||||
group.leave()
|
||||
return
|
||||
}
|
||||
if let resultID = result.0 {
|
||||
song.lyricsID = resultID
|
||||
}
|
||||
@ -104,13 +112,31 @@ class MPPositive_SongViewModel: NSObject {
|
||||
//没有下载过
|
||||
//调用网络请求补全数据
|
||||
improveDataforResouceAndCover(song) { [weak self] resourceUrls, coverUrls in
|
||||
guard let self = self else {return}
|
||||
guard let self = self else {
|
||||
group.leave()
|
||||
return
|
||||
}
|
||||
if let resourceUrls = resourceUrls {
|
||||
song.resourceUrls = resourceUrls.0
|
||||
song.itags = resourceUrls.1
|
||||
song.mimeTypes = resourceUrls.2
|
||||
}
|
||||
song.coverUrls = coverUrls
|
||||
isEmptyResource = false
|
||||
isPlayEntitlement = true
|
||||
group.leave()
|
||||
}failure: { [weak self] statu in
|
||||
guard let self = self else {
|
||||
group.leave()
|
||||
return
|
||||
}
|
||||
//statu为false的情况下,是网络请求错误,为true则是网络正常,但是没有获取到数据
|
||||
if statu == false {
|
||||
isEmptyResource = false
|
||||
}else {
|
||||
//无数据
|
||||
isEmptyResource = true
|
||||
}
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
@ -120,9 +146,9 @@ class MPPositive_SongViewModel: NSObject {
|
||||
guard let self = self else {return}
|
||||
//更新播放资源
|
||||
if let first = song.resourceUrls?.first {
|
||||
//具备资源,可以播放
|
||||
resourcePlayerURL = .init(string:first)
|
||||
if isDlownd == true {
|
||||
|
||||
//下载了
|
||||
resourcePlayerAsset = .init(LocalURL: resourcePlayerURL!, videoId: song.videoId ?? "", title: title ?? "")
|
||||
}else {
|
||||
@ -130,6 +156,11 @@ class MPPositive_SongViewModel: NSObject {
|
||||
resourcePlayerAsset = .init(resourcePlayerURL!, videoId: song.videoId ?? "", title: title ?? "")
|
||||
}
|
||||
resourcePlayerItem = .init(asset: resourcePlayerAsset)
|
||||
}else {
|
||||
//不具备资源,不可以播放
|
||||
if isEmptyResource == false {
|
||||
isPlayEntitlement = false
|
||||
}
|
||||
}
|
||||
//更新歌词
|
||||
if song.lyrics != nil {
|
||||
|
||||
@ -140,6 +140,7 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
||||
self.currentVideo = self.listViewVideos.first(where: {$0.song.videoId == targetVideoId})
|
||||
//只保留最后7首
|
||||
self.listViewVideos = self.listViewVideos.suffix(7)
|
||||
MP_PlayerManager.shared.playerStatuTimerAction()
|
||||
}
|
||||
///重新获取指定歌曲资源
|
||||
func remakeImproveData(_ completion:@escaping (() -> Void)) {
|
||||
|
||||
@ -111,6 +111,8 @@ class MPPositive_MoreSongOperationsViewController: UIViewController, UIViewContr
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
@ -149,6 +151,8 @@ class MPPositive_MoreSongOperationsViewController: UIViewController, UIViewContr
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
@ -187,6 +191,8 @@ class MPPositive_MoreSongOperationsViewController: UIViewController, UIViewContr
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
@ -226,6 +232,8 @@ class MPPositive_MoreSongOperationsViewController: UIViewController, UIViewContr
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
|
||||
@ -6,8 +6,9 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AppLovinSDK
|
||||
///b面tabBar控制器
|
||||
class MPPositive_TabBarController: UITabBarController, UIViewControllerTransitioningDelegate, GADFullScreenContentDelegate {
|
||||
class MPPositive_TabBarController: UITabBarController, UIViewControllerTransitioningDelegate, GADFullScreenContentDelegate, MAAdDelegate {
|
||||
//自定义tabBar
|
||||
private lazy var customTabBar:MPPositive_CustomTabBar = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 72*width))
|
||||
private lazy var bottomView:MPPositive_BottomShowView = .init(frame: .init(x: 0, y: 0, width: 351, height: 82))
|
||||
@ -62,6 +63,13 @@ class MPPositive_TabBarController: UITabBarController, UIViewControllerTransitio
|
||||
addNotification()
|
||||
//触发更新弹窗
|
||||
updateVersionEvent()
|
||||
|
||||
//判断当前的网络,当网络处于不可用状态时,进入离线模式(展示曲库页)
|
||||
guard MP_NetWorkManager.shared.netWorkStatu != .reachable else {
|
||||
return
|
||||
}
|
||||
//离线模式
|
||||
selectedIndex = 2
|
||||
}
|
||||
//监听通知
|
||||
private func addNotification() {
|
||||
@ -129,18 +137,32 @@ extension MPPositive_TabBarController {
|
||||
self?.present(playerVC, animated: true)
|
||||
}
|
||||
}
|
||||
MP_AdMobManager.shared.showPlayInterstitialAdIfAvailable { [weak self] ad in
|
||||
MP_ADSimpleManager.shared.showPlayInterstitialAdIfAvailable { [weak self] (ad, platform) in
|
||||
guard let self = self else {return}
|
||||
if let ad = ad {
|
||||
//判断音乐播放器是否已经播放
|
||||
MP_AdMobManager.shared.isShowingPlayInterstitialAd = true
|
||||
//播放器还未播放,可以弹出广告
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
ad.fullScreenContentDelegate = self
|
||||
ad.present(fromRootViewController: self)
|
||||
if platform {
|
||||
if let ad = ad as? MAInterstitialAd {
|
||||
//修改插页总开关状态
|
||||
MP_AppLovinManager.shared.setInterstitialSwitch(true)
|
||||
MP_AppLovinManager.shared.isShowingPlayInterstitialAd = true
|
||||
ad.delegate = self
|
||||
ad.show()
|
||||
}else {
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
if let ad = ad as? GADInterstitialAd {
|
||||
//判断音乐播放器是否已经播放
|
||||
MP_AdMobManager.shared.isShowingPlayInterstitialAd = true
|
||||
//播放器还未播放,可以弹出广告
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
ad.fullScreenContentDelegate = self
|
||||
ad.present(fromRootViewController: self)
|
||||
}else {
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,18 +258,58 @@ extension MPPositive_TabBarController {
|
||||
if MP_AdMobManager.shared.completePlayInterstitialAdBlock != nil {
|
||||
MP_AdMobManager.shared.completePlayInterstitialAdBlock!()
|
||||
}
|
||||
// //执行加载播放器页面
|
||||
// DispatchQueue.main.async {
|
||||
// [weak self] in
|
||||
// let playerVC = MPPositive_PlayerViewController()
|
||||
// playerVC.modalPresentationStyle = .fullScreen
|
||||
// playerVC.recommendBlock = {
|
||||
// let recommendVC = MPPositive_RecommendViewController(MP_PlayerManager.shared.loadPlayer.currentVideo.song.relatedID)
|
||||
// self?.viewControllers![self?.selectedIndex ?? 0].children[0].navigationController?.pushViewController(recommendVC, animated: false)
|
||||
// }
|
||||
// self?.present(playerVC, animated: true)
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
//MARK: - AppLovin
|
||||
func didLoad(_ ad: MAAd) {
|
||||
|
||||
}
|
||||
|
||||
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
|
||||
|
||||
}
|
||||
|
||||
func didDisplay(_ ad: MAAd) {
|
||||
if ad.adUnitIdentifier == MP_AppLovinManager.shared.playInterstitialAd?.adUnitIdentifier {
|
||||
print("当前展示的广告是播放插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
MP_AnalyticsManager.shared.max_play_showSuccessAction()
|
||||
}
|
||||
}
|
||||
|
||||
func didHide(_ ad: MAAd) {
|
||||
MP_AppLovinManager.shared.interstitialDate = Date()
|
||||
if ad.adUnitIdentifier == MP_AppLovinManager.shared.playInterstitialAd?.adUnitIdentifier {
|
||||
print("当前消失的广告是播放插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
//执行播放插页广告完成事件包
|
||||
if MP_AppLovinManager.shared.completePlayInterstitialAdBlock != nil {
|
||||
MP_AppLovinManager.shared.completePlayInterstitialAdBlock!()
|
||||
}
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func didClick(_ ad: MAAd) {
|
||||
|
||||
}
|
||||
|
||||
func didFail(toDisplay ad: MAAd, withError error: MAError) {
|
||||
MP_AppLovinManager.shared.interstitialDate = Date()
|
||||
|
||||
if ad.adUnitIdentifier == MP_AppLovinManager.shared.playInterstitialAd?.adUnitIdentifier {
|
||||
|
||||
print("播放插页广告展示时出错,广告ID--\(ad.adUnitIdentifier)")
|
||||
MP_AnalyticsManager.shared.max_play_showFailureAction(error.message)
|
||||
//执行播放插页广告完成事件包
|
||||
if MP_AppLovinManager.shared.completePlayInterstitialAdBlock != nil {
|
||||
MP_AppLovinManager.shared.completePlayInterstitialAdBlock!()
|
||||
}
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ class MPPositive_LibraryViewController: MPPositive_BaseViewController, UIViewCon
|
||||
let offlineVC = MPPositive_OfflineSongsViewController()
|
||||
navigationController?.pushViewController(offlineVC, animated: true)
|
||||
}
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
}
|
||||
//MARK: - JXSegmentedTitleDataSource
|
||||
@ -289,7 +289,7 @@ extension MPPositive_LibraryViewController:JXSegmentedListContainerViewDataSourc
|
||||
//展示歌单详情
|
||||
let playListVC = MPPositive_CustomPlayListViewController(item.playList)
|
||||
navigationController?.pushViewController(playListVC, animated: true)
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
return showView
|
||||
default://收藏歌单
|
||||
|
||||
@ -280,7 +280,11 @@ class MPPositive_HomeViewController: MPPositive_BaseViewController, UIViewContro
|
||||
}
|
||||
//上拉加载更多
|
||||
@objc private func footerRefreshContinuationData() {
|
||||
guard MP_NetWorkManager.shared.continuationAndItct != nil else {
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
tableView.mj_footer?.endRefreshing()
|
||||
return
|
||||
}
|
||||
guard (MP_NetWorkManager.shared.continuationAndItct != nil) || (MPPositive_BrowseLoadViewModel.shared.browseModuleLists.isEmpty == true) else {
|
||||
tableView.mj_footer?.endRefreshing()
|
||||
return
|
||||
}
|
||||
@ -588,7 +592,7 @@ extension MPPositive_HomeViewController: UITableViewDataSource, UITableViewDeleg
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("Home")
|
||||
|
||||
@ -249,7 +249,7 @@ class MPPositive_ListShowViewController: MPPositive_BaseViewController, UIViewCo
|
||||
[weak self] in
|
||||
guard let self = self, let item = listOrAlbum.items.first else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("List")
|
||||
@ -277,7 +277,7 @@ class MPPositive_ListShowViewController: MPPositive_BaseViewController, UIViewCo
|
||||
[weak self] in
|
||||
guard let self = self, let item = listOrAlbum.items.randomElement() else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("List")
|
||||
@ -396,7 +396,7 @@ extension MPPositive_ListShowViewController: UITableViewDataSource, UITableViewD
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("List")
|
||||
|
||||
@ -139,7 +139,7 @@ extension MPPositive_MoreContentViewController: UICollectionViewDataSource, UICo
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("MoreContent")
|
||||
|
||||
@ -154,6 +154,26 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
||||
activityIndicator.color = .black
|
||||
return activityIndicator
|
||||
}()
|
||||
//下载引导层
|
||||
private lazy var leadMaskView:UIView = {
|
||||
let maskView = UIView(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height))
|
||||
maskView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(maskMissClick(_ :))))
|
||||
maskView.isUserInteractionEnabled = true
|
||||
maskView.backgroundColor = .init(hex: "#000000", alpha: 0.6)
|
||||
return maskView
|
||||
}()
|
||||
//下载提示层
|
||||
private lazy var leadNoticeView:UIView = {
|
||||
let noticeView:UIView = .init(frame: .init(x: 0, y: 0, width: 120*width, height: 43*width))
|
||||
noticeView.backgroundColor = .clear
|
||||
//添加一个提示弹窗
|
||||
let noticeImageView = UIImageView(image: .init(named: "Click_Download'logo"))
|
||||
noticeView.addSubview(noticeImageView)
|
||||
noticeImageView.snp.makeConstraints { make in
|
||||
make.left.top.right.bottom.equalToSuperview()
|
||||
}
|
||||
return noticeView
|
||||
}()
|
||||
//封面View(封面,标题,副标题,收藏,下载,进度条View)
|
||||
private lazy var coverView:MPPositive_PlayerCoverView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 480*width))
|
||||
//歌词View
|
||||
@ -274,6 +294,12 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
||||
// print("视频Layer移除")
|
||||
// MP_PlayerManager.shared.videoLayer.removeFromSuperlayer()
|
||||
}
|
||||
override func viewWillLayoutSubviews() {
|
||||
super.viewWillLayoutSubviews()
|
||||
if leadMaskView.superview != nil {
|
||||
setMaskLayer()
|
||||
}
|
||||
}
|
||||
//视图配置
|
||||
private func configure() {
|
||||
//导航View内容配置
|
||||
@ -347,6 +373,11 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
||||
make.height.equalTo(42*width)
|
||||
}
|
||||
maskNotReachableView.isHidden = (MP_NetWorkManager.shared.netWorkStatu == .reachable)
|
||||
guard UserDefaults.standard.bool(forKey: "isFristPlayer") != true else {
|
||||
return
|
||||
}
|
||||
UserDefaults.standard.set(true, forKey: "isFristPlayer")
|
||||
view.addSubview(leadMaskView)
|
||||
}
|
||||
//生成一个单选按钮组View
|
||||
private func createSwitchActionView() -> UIView {
|
||||
@ -436,6 +467,30 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
||||
}
|
||||
return bottomView
|
||||
}
|
||||
//设置阴影层
|
||||
private func setMaskLayer() {
|
||||
// 创建一个遮罩层
|
||||
let maskLayer = CAShapeLayer()
|
||||
// 创建全屏路径
|
||||
let path = UIBezierPath(rect: leadMaskView.bounds)
|
||||
// 获取下载按钮的 frame,并计算出要突出显示的圆形区域
|
||||
let buttonFrame = self.coverView.downloadButton.convert(self.coverView.downloadButton.bounds, to: leadMaskView)
|
||||
let circlePath = UIBezierPath(ovalIn: buttonFrame.insetBy(dx: -15, dy: -15)) // 圆形区域比按钮稍大
|
||||
// 将圆形路径添加到全屏路径中(注意使用 `.byReversingPath()` 反转路径,这样圆圈内是透明的)
|
||||
path.append(circlePath.reversing())
|
||||
// 将路径赋值给遮罩层
|
||||
maskLayer.path = path.cgPath
|
||||
// 将遮罩层应用到遮罩视图上
|
||||
leadMaskView.layer.mask = maskLayer
|
||||
view.addSubview(leadNoticeView)
|
||||
leadNoticeView.snp.makeConstraints { make in
|
||||
make.right.equalTo(self.coverView.downloadButton.snp.centerX).offset(43.5*width)
|
||||
make.centerY.equalTo(self.coverView.downloadButton.snp.centerY).offset(-60*width)
|
||||
make.width.equalTo(180*width)
|
||||
make.height.equalTo(64.5*width)
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - 页面渲染
|
||||
private func uploadUI() {
|
||||
DispatchQueue.main.async {
|
||||
@ -557,6 +612,13 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
||||
@objc private func disMissClick(_ sender:UIButton) {
|
||||
dismiss(animated: true)
|
||||
}
|
||||
//引导遮罩层事件
|
||||
@objc private func maskMissClick(_ sender:UITapGestureRecognizer) {
|
||||
view.endEditing(true)
|
||||
sender.view?.removeFromSuperview()
|
||||
leadNoticeView.removeFromSuperview()
|
||||
}
|
||||
|
||||
//切换页面显示内容(单曲封面|歌词)按钮组
|
||||
@objc private func switchActionClick(_ sender:UIButton) {
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
@ -694,7 +756,7 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
||||
}
|
||||
//切歌广告
|
||||
if MP_NetWorkManager.shared.netWorkStatu == .reachable {
|
||||
MP_AdMobManager.shared.showPlayInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showPlayInterstitialAdIfAvailable(nil)
|
||||
}
|
||||
MPPositive_Debouncer.shared.call {
|
||||
[weak self] in
|
||||
@ -712,7 +774,7 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
||||
}
|
||||
//切歌广告
|
||||
if MP_NetWorkManager.shared.netWorkStatu == .reachable {
|
||||
MP_AdMobManager.shared.showPlayInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showPlayInterstitialAdIfAvailable(nil)
|
||||
}
|
||||
MPPositive_Debouncer.shared.call {
|
||||
[weak self] in
|
||||
|
||||
@ -144,7 +144,7 @@ extension MPPositive_GrideMoodViewController: UITableViewDataSource, UITableView
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("Mood")
|
||||
|
||||
@ -125,7 +125,7 @@ extension MPPositive_SearchViewController: UICollectionViewDataSource, UICollect
|
||||
MP_AnalyticsManager.shared.grid_mood_clickAction(item.title ?? "")
|
||||
let moodVC = MPPositive_GrideMoodViewController(item.grid.browseId, params: item.grid.params, title: item.title ?? "")
|
||||
navigationController?.pushViewController(moodVC, animated: false)
|
||||
MP_AdMobManager.shared.showSearchInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showSearchInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +61,16 @@ class MPPositive_CustomTabBarView: UIView {
|
||||
make.centerX.equalToSuperview().multipliedBy(0.45 + 0.55*Double(item.tag))
|
||||
}
|
||||
}
|
||||
//默认首位item处于选中状态
|
||||
tabBarItems[0].isSelected = true
|
||||
//判断是否处于离线模式
|
||||
guard MP_NetWorkManager.shared.netWorkStatu != .reachable else {
|
||||
//默认首位item处于选中状态
|
||||
tabBarItems.first?.isSelected = true
|
||||
selectedItemIndex = 0
|
||||
return
|
||||
}
|
||||
//离线模式
|
||||
tabBarItems.last?.isSelected = true
|
||||
selectedItemIndex = 2
|
||||
}
|
||||
|
||||
//点击事件
|
||||
|
||||
@ -249,7 +249,7 @@ class MPPositive_ArtistShowSongTableViewCell: UITableViewCell, PKDownloadButtonD
|
||||
return
|
||||
}
|
||||
//未下载
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
//切换为准备状态
|
||||
downloadButton.state = .pending
|
||||
//通过网络请求获取当前预览项资源(转为Song)
|
||||
@ -277,6 +277,8 @@ class MPPositive_ArtistShowSongTableViewCell: UITableViewCell, PKDownloadButtonD
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
|
||||
@ -278,7 +278,7 @@ extension MPPositive_ArtistShowTypeView:UITableViewDataSource, UITableViewDelega
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("Artist")
|
||||
|
||||
@ -18,14 +18,19 @@ class MPPositive_HomeLibraryListCollectionViewCell: UICollectionViewCell {
|
||||
}()
|
||||
//标题Label
|
||||
private lazy var titleLabel:UILabel = createLabel("Title", font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .white, textAlignment: .left)
|
||||
//数量Label
|
||||
private lazy var countsLabel:UILabel = createLabel("0", font: .systemFont(ofSize: 25*width, weight: .bold), textColor: .white, textAlignment: .left)
|
||||
var library:MPPositive_LibraryViewModel!{
|
||||
didSet{
|
||||
switch library.library.libraryType {
|
||||
case .custom_playlist:
|
||||
coverImageView.kf.setImage(with: library.cover, placeholder: library.library.libraryType.image)
|
||||
countsLabel.isHidden = true
|
||||
default:
|
||||
coverImageView.image = library.library.libraryType.image
|
||||
countsLabel.isHidden = false
|
||||
}
|
||||
countsLabel.text = "\(library.library.count)"
|
||||
titleLabel.text = library.title
|
||||
}
|
||||
}
|
||||
@ -51,5 +56,11 @@ class MPPositive_HomeLibraryListCollectionViewCell: UICollectionViewCell {
|
||||
make.top.equalTo(coverImageView.snp.bottom).offset(9*width)
|
||||
make.left.right.equalToSuperview()
|
||||
}
|
||||
addSubview(countsLabel)
|
||||
countsLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(8*width)
|
||||
make.right.equalToSuperview().offset(-8*width)
|
||||
make.top.equalToSuperview().offset(8*width)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,6 +121,6 @@ extension MPPositive_HomeLibraryListstableViewCell:UICollectionViewDataSource, U
|
||||
}
|
||||
}
|
||||
}
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,7 +240,7 @@ class MPPositive_HomeSingleCollectionViewCell: UICollectionViewCell, PKDownloadB
|
||||
guard let videoId = itemViewModel.browseItem.videoId else {
|
||||
return
|
||||
}
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
//切换为准备状态
|
||||
downloadButton.state = .pending
|
||||
//通过网络请求获取当前预览项资源(转为Song)
|
||||
@ -268,6 +268,8 @@ class MPPositive_HomeSingleCollectionViewCell: UICollectionViewCell, PKDownloadB
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
|
||||
@ -167,7 +167,7 @@ extension MPPositive_HomeSinglesTableViewCell:UICollectionViewDataSource, UIColl
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
guard let item = (self.browseViewModel?.items[indexPath.row] ?? self.personlViewModel?.items[indexPath.row]) else {
|
||||
|
||||
@ -273,7 +273,7 @@ class MPPositive_MusicItemShowTableViewCell: UITableViewCell, PKDownloadButtonDe
|
||||
guard let videoId = itemView.browseItem.videoId else {
|
||||
return
|
||||
}
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
//切换为准备状态
|
||||
downloadButton.state = .pending
|
||||
//通过网络请求获取当前预览项资源(转为Song)
|
||||
@ -301,6 +301,8 @@ class MPPositive_MusicItemShowTableViewCell: UITableViewCell, PKDownloadButtonDe
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
|
||||
@ -197,7 +197,7 @@ class MPPositive_PersonalisedRecommendationsTableViewCell: UITableViewCell, UIVi
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.home_b_module_clickAction(titleLabel.text ?? "")
|
||||
@ -328,7 +328,7 @@ extension MPPositive_PersonalisedRecommendationsTableViewCell:UICollectionViewDa
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.home_b_module_clickAction(item.browseItem.pageType ?? "")
|
||||
|
||||
@ -347,7 +347,7 @@ class MPPositive_PlayerCoverView: UIView, PKDownloadButtonDelegate {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
return
|
||||
}
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
//切换为准备状态
|
||||
downloadButton.state = .pending
|
||||
//当开始下载时
|
||||
|
||||
@ -94,7 +94,7 @@ class MPPositive_SearchResultPreviewShowView: MPPositive_BaseShowView, JXSegment
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("Search")
|
||||
|
||||
@ -314,7 +314,7 @@ class MPPositive_SearchResultShowTableViewCell: UITableViewCell, PKDownloadButto
|
||||
return
|
||||
}
|
||||
//未下载
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
//切换为准备状态
|
||||
downloadButton.state = .pending
|
||||
//通过网络请求获取当前预览项资源(转为Song)
|
||||
@ -342,6 +342,8 @@ class MPPositive_SearchResultShowTableViewCell: UITableViewCell, PKDownloadButto
|
||||
}
|
||||
first.coverUrls = coverUrls
|
||||
group.leave()
|
||||
} failure: {_ in
|
||||
group.leave()
|
||||
}
|
||||
group.notify(queue: .main, execute: {
|
||||
[weak self] in
|
||||
|
||||
@ -123,7 +123,7 @@ class MPPositive_SearchResultTypeShowView: MPPositive_BaseShowView, JXSegmentedL
|
||||
[weak self] in
|
||||
guard let self = self else {return}
|
||||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||||
MP_HUD.text("Bad connection~".localizableString(), delay: 2.0, completion: nil)
|
||||
playOfflineSongs()
|
||||
return
|
||||
}
|
||||
MP_AnalyticsManager.shared.song_clickAction("Search")
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import AppLovinSDK
|
||||
class MPPositive_SearchResultsShowView: UIView {
|
||||
///搜索结果管理模型
|
||||
var loadModel:MPPositive_SearchResultsLoadViewModel!{
|
||||
@ -18,17 +18,32 @@ class MPPositive_SearchResultsShowView: UIView {
|
||||
emptyImageView.isHidden = false
|
||||
}else {
|
||||
if isShowAd == true {
|
||||
MP_AdMobManager.shared.showSearchInterstitialAdIfAvailable { [weak self] ad in
|
||||
MP_ADSimpleManager.shared.showSearchInterstitialAdIfAvailable { [weak self] ad, platform in
|
||||
guard let self = self else {return}
|
||||
//判断数据是否有值
|
||||
if loadModel?.sectionLists?.count != nil {
|
||||
//有值,不在展示
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(false)
|
||||
if platform {
|
||||
MP_AppLovinManager.shared.setInterstitialSwitch(false)
|
||||
}else {
|
||||
//有值,不在展示
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(false)
|
||||
}
|
||||
}else {
|
||||
MP_AdMobManager.shared.isShowingSearchInterstitialAd = true
|
||||
//没有值,展示
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
ad.present(fromRootViewController: nil)
|
||||
if platform {
|
||||
if let new = ad as? MAInterstitialAd {
|
||||
MP_AppLovinManager.shared.isShowingSearchInterstitialAd = true
|
||||
//没有值,展示
|
||||
MP_AppLovinManager.shared.setInterstitialSwitch(true)
|
||||
new.show()
|
||||
}
|
||||
}else {
|
||||
if let new = ad as? GADInterstitialAd {
|
||||
MP_AdMobManager.shared.isShowingSearchInterstitialAd = true
|
||||
//没有值,展示
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
new.present(fromRootViewController: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,8 +6,9 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AppLovinSDK
|
||||
///A面通用标签栏
|
||||
class MPSideA_TabBarController: UITabBarController, GADFullScreenContentDelegate {
|
||||
class MPSideA_TabBarController: UITabBarController, GADFullScreenContentDelegate, MAAdDelegate {
|
||||
//自定义tabBar
|
||||
private lazy var customTabBar:MPSideA_CustomTabBar = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 72*width))
|
||||
//底部音乐展示View(默认隐藏)
|
||||
@ -169,21 +170,6 @@ extension MPSideA_TabBarController: UIViewControllerTransitioningDelegate {
|
||||
//前往播放器
|
||||
private func pushPlayer() {
|
||||
print("Go to player")
|
||||
MP_AdMobManager.shared.showPlayInterstitialAdIfAvailable { [weak self] ad in
|
||||
guard let self = self else {return}
|
||||
if let ad = ad {
|
||||
//判断音乐播放器是否已经播放
|
||||
MP_AdMobManager.shared.isShowingPlayInterstitialAd = true
|
||||
//播放器还未播放,可以弹出广告
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
ad.fullScreenContentDelegate = self
|
||||
ad.present(fromRootViewController: self)
|
||||
}else {
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
self.pushPlayerBlock = {
|
||||
[weak self] in
|
||||
//执行加载播放器页面
|
||||
@ -194,6 +180,35 @@ extension MPSideA_TabBarController: UIViewControllerTransitioningDelegate {
|
||||
self?.present(playerVC, animated: true)
|
||||
}
|
||||
}
|
||||
MP_ADSimpleManager.shared.showPlayInterstitialAdIfAvailable { [weak self] (ad, platform) in
|
||||
guard let self = self else {return}
|
||||
if platform {
|
||||
if let ad = ad as? MAInterstitialAd {
|
||||
//修改插页总开关状态
|
||||
MP_AppLovinManager.shared.setInterstitialSwitch(true)
|
||||
MP_AppLovinManager.shared.isShowingPlayInterstitialAd = true
|
||||
ad.delegate = self
|
||||
ad.show()
|
||||
}else {
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if let ad = ad as? GADInterstitialAd {
|
||||
//判断音乐播放器是否已经播放
|
||||
MP_AdMobManager.shared.isShowingPlayInterstitialAd = true
|
||||
//播放器还未播放,可以弹出广告
|
||||
MP_AdMobManager.shared.setInterstitialSwitch(true)
|
||||
ad.fullScreenContentDelegate = self
|
||||
ad.present(fromRootViewController: self)
|
||||
}else {
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
|
||||
return MPSideA_PresentationController(presentedViewController: presented, presenting: presenting)
|
||||
@ -325,18 +340,60 @@ extension MPSideA_TabBarController {
|
||||
print("播放插页广告展示时出错,广告ID--\(UUID),具体错误原因:\(error.localizedDescription)")
|
||||
MP_AnalyticsManager.shared.play_ads_showFailureAction(error.localizedDescription)
|
||||
//执行播放插页广告完成事件包
|
||||
//执行播放插页广告完成事件包
|
||||
if MP_AdMobManager.shared.completePlayInterstitialAdBlock != nil {
|
||||
MP_AdMobManager.shared.completePlayInterstitialAdBlock!()
|
||||
}
|
||||
//执行加载播放器页面
|
||||
// DispatchQueue.main.async {
|
||||
// [weak self] in
|
||||
// //模态弹出
|
||||
// let playerVC = MPSideA_PlayerViewController()
|
||||
// self?.present(playerVC, animated: true)
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
//MARK: - AppLovin
|
||||
func didLoad(_ ad: MAAd) {
|
||||
|
||||
}
|
||||
|
||||
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
|
||||
|
||||
}
|
||||
|
||||
func didDisplay(_ ad: MAAd) {
|
||||
if ad.adUnitIdentifier == MP_AppLovinManager.shared.playInterstitialAd?.adUnitIdentifier {
|
||||
print("当前展示的广告是播放插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
MP_AnalyticsManager.shared.max_play_showSuccessAction()
|
||||
}
|
||||
}
|
||||
|
||||
func didHide(_ ad: MAAd) {
|
||||
MP_AppLovinManager.shared.interstitialDate = Date()
|
||||
if ad.adUnitIdentifier == MP_AppLovinManager.shared.playInterstitialAd?.adUnitIdentifier {
|
||||
print("当前消失的广告是播放插页广告,广告ID--\(ad.adUnitIdentifier)")
|
||||
|
||||
//执行播放插页广告完成事件包
|
||||
if MP_AppLovinManager.shared.completePlayInterstitialAdBlock != nil {
|
||||
MP_AppLovinManager.shared.completePlayInterstitialAdBlock!()
|
||||
}
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func didClick(_ ad: MAAd) {
|
||||
|
||||
}
|
||||
|
||||
func didFail(toDisplay ad: MAAd, withError error: MAError) {
|
||||
MP_AppLovinManager.shared.interstitialDate = Date()
|
||||
|
||||
if ad.adUnitIdentifier == MP_AppLovinManager.shared.playInterstitialAd?.adUnitIdentifier {
|
||||
print("播放插页广告展示时出错,广告ID--\(ad.adUnitIdentifier)")
|
||||
MP_AnalyticsManager.shared.max_play_showFailureAction(error.message)
|
||||
//执行播放插页广告完成事件包
|
||||
if MP_AppLovinManager.shared.completePlayInterstitialAdBlock != nil {
|
||||
MP_AppLovinManager.shared.completePlayInterstitialAdBlock!()
|
||||
}
|
||||
if let block = self.pushPlayerBlock {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ class MPSideA_CenterViewController: MPSideA_BaseViewController {
|
||||
[weak self] in
|
||||
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 0.3) {
|
||||
[weak self] in
|
||||
MP_AdMobManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showLibraryInterstitialAdIfAvailable(completion: nil)
|
||||
}
|
||||
}
|
||||
navigationController?.pushViewController(setVC, animated: true)
|
||||
|
||||
@ -254,7 +254,7 @@ extension MPSideA_PlayerViewController {
|
||||
//关闭麦克风监听器
|
||||
MPSideA_MediaCenterManager.shared.stopMonitor()
|
||||
//弹出切割广告
|
||||
MP_AdMobManager.shared.showPlayInterstitialAdIfAvailable(completion: nil)
|
||||
MP_ADSimpleManager.shared.showPlayInterstitialAdIfAvailable(nil)
|
||||
guard let music = MPSideA_MediaCenterManager.shared.getMusic() else {
|
||||
//播放器未能持有音乐实体
|
||||
print("No Data Music")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user