b面正式版-1.0.2
This commit is contained in:
parent
62deb230c0
commit
475a5d56c4
@ -1554,11 +1554,10 @@
|
|||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = MusicPlayer/Info.plist;
|
INFOPLIST_FILE = MusicPlayer/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Musiclax;
|
INFOPLIST_KEY_CFBundleDisplayName = Musiclax;
|
||||||
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
|
||||||
INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
|
||||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
||||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "\"Musiclax\" requires you to turn on the microphone to recognize surrounding decibels and automatically turn on white noise for you. Do you allow this application to obtain your microphone permissions?";
|
INFOPLIST_KEY_NSMicrophoneUsageDescription = "\"Musiclax\" requires you to turn on the microphone to recognize surrounding decibels and automatically turn on white noise for you. Do you allow this application to obtain your microphone permissions?";
|
||||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "\"Musiclax\" requires opening your album to obtain photos, which are used to add your custom white noise. Do you want to allow this application to obtain your album permissions?";
|
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "\"Musiclax\" requires opening your album to obtain photos, which are used to add your custom white noise. Do you want to allow this application to obtain your album permissions?";
|
||||||
|
INFOPLIST_KEY_NSUserTrackingUsageDescription = "\"Musiclax\" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties.";
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||||
@ -1598,11 +1597,10 @@
|
|||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = MusicPlayer/Info.plist;
|
INFOPLIST_FILE = MusicPlayer/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Musiclax;
|
INFOPLIST_KEY_CFBundleDisplayName = Musiclax;
|
||||||
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
|
||||||
INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
|
||||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!";
|
||||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "\"Musiclax\" requires you to turn on the microphone to recognize surrounding decibels and automatically turn on white noise for you. Do you allow this application to obtain your microphone permissions?";
|
INFOPLIST_KEY_NSMicrophoneUsageDescription = "\"Musiclax\" requires you to turn on the microphone to recognize surrounding decibels and automatically turn on white noise for you. Do you allow this application to obtain your microphone permissions?";
|
||||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "\"Musiclax\" requires opening your album to obtain photos, which are used to add your custom white noise. Do you want to allow this application to obtain your album permissions?";
|
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "\"Musiclax\" requires opening your album to obtain photos, which are used to add your custom white noise. Do you want to allow this application to obtain your album permissions?";
|
||||||
|
INFOPLIST_KEY_NSUserTrackingUsageDescription = "\"Musiclax\" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties.";
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||||
|
|||||||
22
MusicPlayer/Assets.xcassets/placeholder.imageset/Contents.json
vendored
Normal file
22
MusicPlayer/Assets.xcassets/placeholder.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag 1.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -4,12 +4,11 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>UIBackgroundModes</key>
|
<key>UIBackgroundModes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>fetch</string>
|
<string>audio</string>
|
||||||
<string>backgroundFetch</string>
|
<string>backgroundFetch</string>
|
||||||
|
<string>fetch</string>
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>NSUserTrackingUsageDescription</key>
|
|
||||||
<string>"Musiclax" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties.</string>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -31,8 +31,6 @@ class MP_LunchViewController: UIViewController {
|
|||||||
timer.add(to: RunLoop.current, forMode: .common)
|
timer.add(to: RunLoop.current, forMode: .common)
|
||||||
//获取idfa
|
//获取idfa
|
||||||
_ = requestTrackingAuthorization(self)
|
_ = requestTrackingAuthorization(self)
|
||||||
//获取定位权限
|
|
||||||
MP_LocationManager.shared.setLocationPermission(self, complete: nil)
|
|
||||||
MP_AnalyticsManager.shared.getOpenStatus { [weak self] open in
|
MP_AnalyticsManager.shared.getOpenStatus { [weak self] open in
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
if open {
|
if open {
|
||||||
|
|||||||
@ -51,7 +51,7 @@ var app_Version:String{
|
|||||||
///底部安全区域
|
///底部安全区域
|
||||||
let bottomPadding = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
|
let bottomPadding = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
|
||||||
///全局占位图
|
///全局占位图
|
||||||
let placeholderImage:UIImage = UIImage(named: "Home First'placeholder")!
|
let placeholderImage:UIImage = UIImage(named: "placeholder")!
|
||||||
///隐私政策网址
|
///隐私政策网址
|
||||||
let privacyUrl:URL = .init(string: "https://musiclax.mystrikingly.com/privacy")!
|
let privacyUrl:URL = .init(string: "https://musiclax.mystrikingly.com/privacy")!
|
||||||
///用户协议网址
|
///用户协议网址
|
||||||
@ -167,7 +167,7 @@ func switchPlayTypeBtnIcon(_ btn:UIButton) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
///请求广告授权
|
///请求广告授权
|
||||||
func requestTrackingAuthorization(_ observe:UIViewController) -> Bool {
|
func requestTrackingAuthorization(_ observe:UIViewController,max:Int = 0) -> Bool {
|
||||||
if #available(iOS 14, *) {
|
if #available(iOS 14, *) {
|
||||||
// 检查当前的跟踪管理器状态
|
// 检查当前的跟踪管理器状态
|
||||||
let status = ATTrackingManager.trackingAuthorizationStatus
|
let status = ATTrackingManager.trackingAuthorizationStatus
|
||||||
@ -178,7 +178,10 @@ func requestTrackingAuthorization(_ observe:UIViewController) -> Bool {
|
|||||||
ATTrackingManager.requestTrackingAuthorization { status in
|
ATTrackingManager.requestTrackingAuthorization { status in
|
||||||
let isAuthorized = status == .authorized
|
let isAuthorized = status == .authorized
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
_ = requestTrackingAuthorization(observe)
|
let new = max + 1
|
||||||
|
if new < 3 {
|
||||||
|
_ = requestTrackingAuthorization(observe, max: new)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .authorized:
|
case .authorized:
|
||||||
|
|||||||
@ -8,160 +8,160 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import CoreLocation
|
import CoreLocation
|
||||||
|
|
||||||
class MP_LocationManager: NSObject {
|
//class MP_LocationManager: NSObject {
|
||||||
static let shared = MP_LocationManager()
|
// static let shared = MP_LocationManager()
|
||||||
var getAuthHandle: ((_ success: Bool) -> Void)?
|
// var getAuthHandle: ((_ success: Bool) -> Void)?
|
||||||
//位置管理
|
// //位置管理
|
||||||
private var locationManager: CLLocationManager!
|
// private var locationManager: CLLocationManager!
|
||||||
//定位信息(字符串)
|
// //定位信息(字符串)
|
||||||
private var location:String = "US"
|
// private var location:String = "US"
|
||||||
override init() {
|
// override init() {
|
||||||
super.init()
|
// super.init()
|
||||||
locationManager = CLLocationManager()
|
// locationManager = CLLocationManager()
|
||||||
//设置了精度最差的 3公里内 kCLLocationAccuracyThreeKilometers
|
// //设置了精度最差的 3公里内 kCLLocationAccuracyThreeKilometers
|
||||||
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
|
// locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
|
||||||
locationManager.delegate = self
|
// locationManager.delegate = self
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// 获取定位权限并处理新事件
|
// /// 获取定位权限并处理新事件
|
||||||
/// - Parameter complete: 尾随事件
|
// /// - Parameter complete: 尾随事件
|
||||||
func setLocationPermission(_ viewController:UIViewController ,complete:(() -> Void)?) {
|
// func setLocationPermission(_ viewController:UIViewController ,complete:(() -> Void)?) {
|
||||||
if MP_LocationManager().hasLocationPermission() == true {
|
// if MP_LocationManager().hasLocationPermission() == true {
|
||||||
//成功获取权限
|
// //成功获取权限
|
||||||
if complete != nil {
|
// if complete != nil {
|
||||||
complete!()
|
// complete!()
|
||||||
}
|
// }
|
||||||
}else {
|
// }else {
|
||||||
//未获取权限
|
// //未获取权限
|
||||||
switch MP_LocationManager().locationPermission() {
|
// switch MP_LocationManager().locationPermission() {
|
||||||
case .notDetermined:
|
// case .notDetermined:
|
||||||
MP_LocationManager().requestLocationAuthorizaiton()
|
// MP_LocationManager().requestLocationAuthorizaiton()
|
||||||
case .restricted, .denied:
|
// case .restricted, .denied:
|
||||||
DispatchQueue.main.async {
|
// DispatchQueue.main.async {
|
||||||
let alertController = UIAlertController(title: "Location permission request", message: "“Musiclax” needs to obtain your location information in order to refine the preview music information provided to you!", preferredStyle: .alert)
|
// let alertController = UIAlertController(title: "Location permission request", message: "“Musiclax” needs to obtain your location information in order to refine the preview music information provided to you!", preferredStyle: .alert)
|
||||||
let CancelAction = UIAlertAction(title:"Cancel", style: .cancel)
|
// let CancelAction = UIAlertAction(title:"Cancel", style: .cancel)
|
||||||
let OKAction = UIAlertAction(title: "Settings", style: .default) { (action) in
|
// let OKAction = UIAlertAction(title: "Settings", style: .default) { (action) in
|
||||||
let url = URL(string: UIApplication.openSettingsURLString)
|
// let url = URL(string: UIApplication.openSettingsURLString)
|
||||||
if let url = url,UIApplication.shared.canOpenURL(url){
|
// if let url = url,UIApplication.shared.canOpenURL(url){
|
||||||
if #available(iOS 10, *) {
|
// if #available(iOS 10, *) {
|
||||||
UIApplication.shared.open(url, options:[:], completionHandler: nil)
|
// UIApplication.shared.open(url, options:[:], completionHandler: nil)
|
||||||
}else{
|
// }else{
|
||||||
UIApplication.shared.canOpenURL(url)
|
// UIApplication.shared.canOpenURL(url)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
alertController.addAction(CancelAction)
|
// alertController.addAction(CancelAction)
|
||||||
alertController.addAction(OKAction)
|
// alertController.addAction(OKAction)
|
||||||
viewController.present(alertController, animated: true, completion: nil)
|
// viewController.present(alertController, animated: true, completion: nil)
|
||||||
}
|
// }
|
||||||
default:
|
// default:
|
||||||
if complete != nil {
|
// if complete != nil {
|
||||||
complete!()
|
// complete!()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// 设备是否开启了定位服务
|
// /// 设备是否开启了定位服务
|
||||||
fileprivate func hasLocationService() -> Bool {
|
// fileprivate func hasLocationService() -> Bool {
|
||||||
|
//
|
||||||
return CLLocationManager.locationServicesEnabled()
|
// return CLLocationManager.locationServicesEnabled()
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
/// APP是否有定位权限
|
// /// APP是否有定位权限
|
||||||
fileprivate func hasLocationPermission() -> Bool {
|
// fileprivate func hasLocationPermission() -> Bool {
|
||||||
|
//
|
||||||
switch locationPermission() {
|
// switch locationPermission() {
|
||||||
case .notDetermined, .restricted, .denied:
|
// case .notDetermined, .restricted, .denied:
|
||||||
return false
|
// return false
|
||||||
case .authorizedWhenInUse, .authorizedAlways:
|
// case .authorizedWhenInUse, .authorizedAlways:
|
||||||
return true
|
// return true
|
||||||
default:
|
// default:
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
return false
|
// return false
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// 定位的权限
|
// /// 定位的权限
|
||||||
fileprivate func locationPermission() -> CLAuthorizationStatus {
|
// fileprivate func locationPermission() -> CLAuthorizationStatus {
|
||||||
if #available(iOS 14.0, *) {
|
// if #available(iOS 14.0, *) {
|
||||||
let status: CLAuthorizationStatus = locationManager.authorizationStatus
|
// let status: CLAuthorizationStatus = locationManager.authorizationStatus
|
||||||
print("location authorizationStatus is \(status.rawValue)")
|
// print("location authorizationStatus is \(status.rawValue)")
|
||||||
return status
|
// return status
|
||||||
} else {
|
// } else {
|
||||||
let status = CLLocationManager.authorizationStatus()
|
// let status = CLLocationManager.authorizationStatus()
|
||||||
print("location authorizationStatus is \(status.rawValue)")
|
// print("location authorizationStatus is \(status.rawValue)")
|
||||||
return status
|
// return status
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
//MARK: - 获取权限,在代理‘didChangeAuthorization’中拿到结果
|
// //MARK: - 获取权限,在代理‘didChangeAuthorization’中拿到结果
|
||||||
func requestLocationAuthorizaiton() {
|
// func requestLocationAuthorizaiton() {
|
||||||
locationManager.requestWhenInUseAuthorization()
|
// locationManager.requestWhenInUseAuthorization()
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
//MARK: - 获取位置
|
// //MARK: - 获取位置
|
||||||
func requestLocation() -> String {
|
// func requestLocation() -> String {
|
||||||
//请求地理位置
|
// //请求地理位置
|
||||||
locationManager.requestLocation()
|
// locationManager.requestLocation()
|
||||||
return location
|
// return location
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
extension MP_LocationManager: CLLocationManagerDelegate {
|
//extension MP_LocationManager: CLLocationManagerDelegate {
|
||||||
//MARK: - ios 14.0 之前,获取权限结果的方法
|
// //MARK: - ios 14.0 之前,获取权限结果的方法
|
||||||
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
|
// func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
|
||||||
handleChangedAuthorization()
|
// handleChangedAuthorization()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
//MARK: - ios 14.0,获取权限结果的方法
|
// //MARK: - ios 14.0,获取权限结果的方法
|
||||||
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
// func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
||||||
handleChangedAuthorization()
|
// handleChangedAuthorization()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private func handleChangedAuthorization() {
|
// private func handleChangedAuthorization() {
|
||||||
if let block = getAuthHandle, locationPermission() != .notDetermined {
|
// if let block = getAuthHandle, locationPermission() != .notDetermined {
|
||||||
if hasLocationPermission() {
|
// if hasLocationPermission() {
|
||||||
block(true)
|
// block(true)
|
||||||
} else {
|
// } else {
|
||||||
block(false)
|
// block(false)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
//MARK: - 获取定位后的位置
|
// //MARK: - 获取定位后的位置
|
||||||
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
// func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
||||||
if let loction = locations.last {
|
// if let loction = locations.last {
|
||||||
//成功获取定位
|
// //成功获取定位
|
||||||
print("latitude: \(loction.coordinate.latitude) longitude:\(loction.coordinate.longitude)")
|
// print("latitude: \(loction.coordinate.latitude) longitude:\(loction.coordinate.longitude)")
|
||||||
let geocoder = CLGeocoder()
|
// let geocoder = CLGeocoder()
|
||||||
geocoder.reverseGeocodeLocation(loction) { (placemarks, error) in
|
// geocoder.reverseGeocodeLocation(loction) { (placemarks, error) in
|
||||||
if let placemark = placemarks?.first {
|
// if let placemark = placemarks?.first {
|
||||||
//编码成功
|
// //编码成功
|
||||||
if let area = placemark.administrativeArea, !area.isEmpty {
|
// if let area = placemark.administrativeArea, !area.isEmpty {
|
||||||
print("Area code: \(area)")
|
// print("Area code: \(area)")
|
||||||
self.location = area
|
// self.location = area
|
||||||
} else if let locality = placemark.locality, !locality.isEmpty {
|
// } else if let locality = placemark.locality, !locality.isEmpty {
|
||||||
print("Area code: \(locality)")
|
// print("Area code: \(locality)")
|
||||||
self.location = locality
|
// self.location = locality
|
||||||
} else if let country = placemark.country, !country.isEmpty {
|
// } else if let country = placemark.country, !country.isEmpty {
|
||||||
print("Country code: \(country)")
|
// print("Country code: \(country)")
|
||||||
self.location = country
|
// self.location = country
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if let error = error {
|
// if let error = error {
|
||||||
print("Reverse geocoding failure: \(error.localizedDescription)")
|
// print("Reverse geocoding failure: \(error.localizedDescription)")
|
||||||
//编码失败,默认设置位置是US
|
// //编码失败,默认设置位置是US
|
||||||
self.location = "US"
|
// self.location = "US"
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
// func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
||||||
print("Reverse geocoding failure: \(error.localizedDescription)")
|
// print("Reverse geocoding failure: \(error.localizedDescription)")
|
||||||
//编码失败,默认设置位置是US
|
// //编码失败,默认设置位置是US
|
||||||
self.location = "US"
|
// self.location = "US"
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@ -40,7 +40,8 @@ class MP_NetWorkManager: NSObject {
|
|||||||
///YouTuBe资源键值
|
///YouTuBe资源键值
|
||||||
private let youTubeKeys:[String] = ["MUSIC_VIDEO_TYPE_ATV","MUSIC_VIDEO_TYPE_OMV","MUSIC_PAGE_TYPE_ALBUM","MUSIC_PAGE_TYPE_ARTIST","MUSIC_PAGE_TYPE_PLAYLIST","MUSIC_PAGE_TYPE_TRACK_LYRICS","MUSIC_PAGE_TYPE_TRACK_RELATED"]
|
private let youTubeKeys:[String] = ["MUSIC_VIDEO_TYPE_ATV","MUSIC_VIDEO_TYPE_OMV","MUSIC_PAGE_TYPE_ALBUM","MUSIC_PAGE_TYPE_ARTIST","MUSIC_PAGE_TYPE_PLAYLIST","MUSIC_PAGE_TYPE_TRACK_LYRICS","MUSIC_PAGE_TYPE_TRACK_RELATED"]
|
||||||
///禁止接入IP信息组
|
///禁止接入IP信息组
|
||||||
private let banIPs:[String] = ["CN",
|
private let banIPs:[String] = [
|
||||||
|
"CN",
|
||||||
"HK",
|
"HK",
|
||||||
"TW",
|
"TW",
|
||||||
"JP",
|
"JP",
|
||||||
@ -49,7 +50,8 @@ class MP_NetWorkManager: NSObject {
|
|||||||
"CH",
|
"CH",
|
||||||
"BE",
|
"BE",
|
||||||
"MO",
|
"MO",
|
||||||
"SG"]
|
"SG"
|
||||||
|
]
|
||||||
//网络状态
|
//网络状态
|
||||||
enum NetWorkStatus: String {
|
enum NetWorkStatus: String {
|
||||||
case notReachable = "网络不可用"
|
case notReachable = "网络不可用"
|
||||||
@ -80,7 +82,7 @@ class MP_NetWorkManager: NSObject {
|
|||||||
//固定时间点(同一天的上一周)
|
//固定时间点(同一天的上一周)
|
||||||
private lazy var currTimeDate:String = (Date().timeZone() - 7.days).toString(.custom("YYYYMMdd"))
|
private lazy var currTimeDate:String = (Date().timeZone() - 7.days).toString(.custom("YYYYMMdd"))
|
||||||
///地址
|
///地址
|
||||||
private lazy var locaton:String = MP_LocationManager.shared.requestLocation()
|
private var locaton:String?
|
||||||
//预览下一阶段参数(网络请求获取)
|
//预览下一阶段参数(网络请求获取)
|
||||||
private var continuationAndItct:(String?,String?){
|
private var continuationAndItct:(String?,String?){
|
||||||
willSet{
|
willSet{
|
||||||
@ -108,7 +110,7 @@ class MP_NetWorkManager: NSObject {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -214,10 +216,12 @@ extension MP_NetWorkManager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if banIPs.contains(code) == true {
|
if banIPs.contains(code) == true {
|
||||||
|
locaton = ""
|
||||||
//包含,是禁止区域
|
//包含,是禁止区域
|
||||||
completion(false)
|
completion(false)
|
||||||
}else {
|
}else {
|
||||||
//不包含,是通行区域
|
//不包含,是通行区域
|
||||||
|
locaton = code
|
||||||
completion(true)
|
completion(true)
|
||||||
}
|
}
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
@ -260,7 +264,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -324,7 +328,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -381,7 +385,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -437,7 +441,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -490,7 +494,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -544,7 +548,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -595,7 +599,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -697,7 +701,7 @@ extension MP_NetWorkManager {
|
|||||||
// //语言
|
// //语言
|
||||||
// "hl":Language_first_local,
|
// "hl":Language_first_local,
|
||||||
// //地址
|
// //地址
|
||||||
// "gl":locaton
|
// "gl":locaton ?? ""
|
||||||
// ]
|
// ]
|
||||||
// ],
|
// ],
|
||||||
// "playbackContext": [
|
// "playbackContext": [
|
||||||
@ -754,7 +758,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -801,7 +805,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -854,7 +858,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -905,7 +909,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -962,7 +966,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -1019,7 +1023,7 @@ extension MP_NetWorkManager {
|
|||||||
//语言
|
//语言
|
||||||
"hl":Language_first_local,
|
"hl":Language_first_local,
|
||||||
//地址
|
//地址
|
||||||
"gl":locaton
|
"gl":locaton ?? ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -1591,7 +1595,7 @@ extension MP_NetWorkManager {
|
|||||||
contents.forEach { content in
|
contents.forEach { content in
|
||||||
//生成更多内容块
|
//生成更多内容块
|
||||||
let item = MPPositive_BrowseItemModel()
|
let item = MPPositive_BrowseItemModel()
|
||||||
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer, (musicResponsiveListItemRenderer.playlistItemData != nil || musicResponsiveListItemRenderer.navigationEndpoint != nil) && (musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE"){
|
||||||
//设置预览图
|
//设置预览图
|
||||||
item.coverUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""})
|
item.coverUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""})
|
||||||
//设置一级标题与二级标题
|
//设置一级标题与二级标题
|
||||||
@ -1614,7 +1618,7 @@ extension MP_NetWorkManager {
|
|||||||
//是专辑列表/艺术家
|
//是专辑列表/艺术家
|
||||||
item.browseId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId
|
item.browseId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
let pageType = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
let pageType = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
||||||
if youTubeKeys.contains(pageType ?? "") == true {
|
if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
//判断细分
|
//判断细分
|
||||||
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
||||||
item.artistId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId
|
item.artistId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
@ -1627,7 +1631,7 @@ extension MP_NetWorkManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if item.title != nil && item.itemType != nil {
|
if item.title != nil && item.itemType != nil, item.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
resultList.previewItemViews.append(.init(item))
|
resultList.previewItemViews.append(.init(item))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1643,6 +1647,72 @@ extension MP_NetWorkManager {
|
|||||||
musicShelfRenderer.contents?.forEach({ content in
|
musicShelfRenderer.contents?.forEach({ content in
|
||||||
//专辑/列表/单曲视频/艺术家
|
//专辑/列表/单曲视频/艺术家
|
||||||
let item = MPPositive_BrowseItemModel()
|
let item = MPPositive_BrowseItemModel()
|
||||||
|
if (content.musicResponsiveListItemRenderer?.playlistItemData != nil || content.musicResponsiveListItemRenderer?.navigationEndpoint != nil) && (content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE") {
|
||||||
|
//设置内容块的封面
|
||||||
|
item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""})
|
||||||
|
//设置一级标题与二级标题
|
||||||
|
for (index, flexColumn) in (content.musicResponsiveListItemRenderer?.flexColumns ?? []).enumerated() {
|
||||||
|
if index == 0 {
|
||||||
|
//一级标题
|
||||||
|
item.title = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
||||||
|
item.pageType = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.first?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
||||||
|
}else {
|
||||||
|
//二级标题
|
||||||
|
item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.playListId = content.musicResponsiveListItemRenderer?.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId
|
||||||
|
//设置id和类型
|
||||||
|
if content.musicResponsiveListItemRenderer?.playlistItemData != nil {
|
||||||
|
//是单曲
|
||||||
|
item.itemType = .single
|
||||||
|
item.videoId = content.musicResponsiveListItemRenderer?.playlistItemData?.videoId
|
||||||
|
}else {
|
||||||
|
//是专辑列表/艺术家
|
||||||
|
item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
|
let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
||||||
|
if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
|
//判断细分
|
||||||
|
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
||||||
|
item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
|
//是艺术家
|
||||||
|
item.itemType = .artist
|
||||||
|
}else {
|
||||||
|
//是列表/专辑
|
||||||
|
item.itemType = .list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if item.itemType != nil, item.title != nil, item.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
|
resultList.previewItemViews.append(.init(item))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//设置query和params值
|
||||||
|
if let searchEndpoint = musicShelfRenderer.bottomEndpoint?.searchEndpoint {
|
||||||
|
resultList.query = searchEndpoint.query
|
||||||
|
resultList.params = searchEndpoint.params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultListSections.append(resultList)
|
||||||
|
}
|
||||||
|
resultListSections.forEach { list in
|
||||||
|
list.previewItemViews = list.previewItemViews.filter({ item in
|
||||||
|
return item.item.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
resultListSections = resultListSections.filter({$0.previewItemViews.count != 0})
|
||||||
|
return resultListSections
|
||||||
|
}
|
||||||
|
///解析搜索分页结果
|
||||||
|
private func parsingSearchTypeResults(_ musicShelfRenderer:JsonSearchTypeResults.Contents.TabbedSearchResultsRenderer.Tab.TabRenderer.Content.SectionListRenderer.Content.MusicShelfRenderer) -> ([MPPositive_SearchResultItemViewModel], String?, String?) {
|
||||||
|
var array:[MPPositive_SearchResultItemViewModel] = []
|
||||||
|
if let contents = musicShelfRenderer.contents {
|
||||||
|
///解析内容块
|
||||||
|
contents.forEach({ content in
|
||||||
|
//专辑/列表/单曲视频/艺术家
|
||||||
|
let item = MPPositive_BrowseItemModel()
|
||||||
|
if (content.musicResponsiveListItemRenderer?.playlistItemData != nil || content.musicResponsiveListItemRenderer?.navigationEndpoint != nil) && (content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE") {
|
||||||
//设置内容块的封面
|
//设置内容块的封面
|
||||||
item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""})
|
item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""})
|
||||||
//设置一级标题与二级标题
|
//设置一级标题与二级标题
|
||||||
@ -1665,7 +1735,7 @@ extension MP_NetWorkManager {
|
|||||||
//是专辑列表/艺术家
|
//是专辑列表/艺术家
|
||||||
item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
||||||
if youTubeKeys.contains(pageType ?? "") == true {
|
if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
//判断细分
|
//判断细分
|
||||||
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
||||||
item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
@ -1677,67 +1747,12 @@ extension MP_NetWorkManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//添加内容块
|
||||||
if item.itemType != nil {
|
if item.itemType != nil {
|
||||||
resultList.previewItemViews.append(.init(item))
|
array.append(.init(item))
|
||||||
}
|
|
||||||
})
|
|
||||||
//设置query和params值
|
|
||||||
if let searchEndpoint = musicShelfRenderer.bottomEndpoint?.searchEndpoint {
|
|
||||||
resultList.query = searchEndpoint.query
|
|
||||||
resultList.params = searchEndpoint.params
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resultListSections.append(resultList)
|
|
||||||
}
|
|
||||||
resultListSections = resultListSections.filter({$0.previewItemViews.count != 0})
|
|
||||||
return resultListSections
|
|
||||||
}
|
|
||||||
///解析搜索分页结果
|
|
||||||
private func parsingSearchTypeResults(_ musicShelfRenderer:JsonSearchTypeResults.Contents.TabbedSearchResultsRenderer.Tab.TabRenderer.Content.SectionListRenderer.Content.MusicShelfRenderer) -> ([MPPositive_SearchResultItemViewModel], String?, String?) {
|
|
||||||
var array:[MPPositive_SearchResultItemViewModel] = []
|
|
||||||
if let contents = musicShelfRenderer.contents {
|
|
||||||
///解析内容块
|
|
||||||
contents.forEach({ content in
|
|
||||||
//专辑/列表/单曲视频/艺术家
|
|
||||||
let item = MPPositive_BrowseItemModel()
|
|
||||||
//设置内容块的封面
|
|
||||||
item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""})
|
|
||||||
//设置一级标题与二级标题
|
|
||||||
for (index, flexColumn) in (content.musicResponsiveListItemRenderer?.flexColumns ?? []).enumerated() {
|
|
||||||
if index == 0 {
|
|
||||||
//一级标题
|
|
||||||
item.title = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
|
||||||
}else {
|
|
||||||
//二级标题
|
|
||||||
item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item.playListId = content.musicResponsiveListItemRenderer?.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId
|
|
||||||
//设置id和类型
|
|
||||||
if content.musicResponsiveListItemRenderer?.playlistItemData != nil {
|
|
||||||
//是单曲
|
|
||||||
item.itemType = .single
|
|
||||||
item.videoId = content.musicResponsiveListItemRenderer?.playlistItemData?.videoId
|
|
||||||
}else {
|
|
||||||
//是专辑列表/艺术家
|
|
||||||
item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
|
||||||
let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
|
||||||
if youTubeKeys.contains(pageType ?? "") == true {
|
|
||||||
//判断细分
|
|
||||||
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
|
||||||
item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
|
||||||
//是艺术家
|
|
||||||
item.itemType = .artist
|
|
||||||
}else {
|
|
||||||
//是列表/专辑
|
|
||||||
item.itemType = .list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//添加内容块
|
|
||||||
if item.itemType != nil {
|
|
||||||
array.append(.init(item))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
var continuation:String?
|
var continuation:String?
|
||||||
@ -1780,7 +1795,7 @@ extension MP_NetWorkManager {
|
|||||||
//是专辑列表/艺术家
|
//是专辑列表/艺术家
|
||||||
item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
||||||
if youTubeKeys.contains(pageType ?? "") == true {
|
if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
//判断细分
|
//判断细分
|
||||||
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
||||||
item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
||||||
@ -1840,17 +1855,19 @@ extension MP_NetWorkManager {
|
|||||||
}
|
}
|
||||||
if let navigationEndpoint = musicResponsiveListItemRenderer.navigationEndpoint {
|
if let navigationEndpoint = musicResponsiveListItemRenderer.navigationEndpoint {
|
||||||
//是专辑列表艺术家
|
//是专辑列表艺术家
|
||||||
if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" && navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
//是艺术家
|
//是艺术家
|
||||||
item.itemType = .artist
|
item.itemType = .artist
|
||||||
item.artistId = navigationEndpoint.browseEndpoint?.browseId
|
item.artistId = navigationEndpoint.browseEndpoint?.browseId
|
||||||
item.pageType = "MUSIC_PAGE_TYPE_ARTIST"
|
item.pageType = "MUSIC_PAGE_TYPE_ARTIST"
|
||||||
}else {
|
}else {
|
||||||
//是专辑列表
|
if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
||||||
item.itemType = .list
|
//是专辑列表
|
||||||
item.pageType = navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
item.itemType = .list
|
||||||
item.browseId = navigationEndpoint.browseEndpoint?.browseId
|
item.pageType = navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
||||||
item.params = navigationEndpoint.browseEndpoint?.params
|
item.browseId = navigationEndpoint.browseEndpoint?.browseId
|
||||||
|
item.params = navigationEndpoint.browseEndpoint?.params
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item
|
return item
|
||||||
|
|||||||
@ -258,6 +258,20 @@ class MP_PlayerManager:NSObject{
|
|||||||
if playState != .Playing {
|
if playState != .Playing {
|
||||||
//当statuVlaue值等于playerItem准备播放的值,说明已经准备好播放
|
//当statuVlaue值等于playerItem准备播放的值,说明已经准备好播放
|
||||||
print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 已经准备好播放")
|
print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 已经准备好播放")
|
||||||
|
// if playState != .Playing {
|
||||||
|
// player.play()
|
||||||
|
// playState = .Playing
|
||||||
|
// //暂停计时器,并获取延时值
|
||||||
|
// suspendTimer()
|
||||||
|
// let times = Int(self.times)
|
||||||
|
// let msTimes = times*1000
|
||||||
|
// MP_AnalyticsManager.shared.player_b_delay_actionAction(loadPlayer.currentVideo?.song.videoId ?? "", videoname: loadPlayer.currentVideo?.title ?? "", artistname: loadPlayer.currentVideo?.song.shortBylineText ?? "", delay: "\(msTimes)ms")
|
||||||
|
// MP_AnalyticsManager.shared.player_b_success_actionAction(loadPlayer.currentVideo?.song.videoId ?? "", videoname: loadPlayer.currentVideo?.title ?? "", artistname: loadPlayer.currentVideo?.song.shortBylineText ?? "")
|
||||||
|
// //执行开始播放闭包
|
||||||
|
// if startActionBlock != nil {
|
||||||
|
// startActionBlock!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 未做好准备播放,失败原因是\(loadPlayer.currentVideo?.resourcePlayerItem.error?.localizedDescription ?? "")")
|
print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 未做好准备播放,失败原因是\(loadPlayer.currentVideo?.resourcePlayerItem.error?.localizedDescription ?? "")")
|
||||||
@ -295,7 +309,7 @@ class MP_PlayerManager:NSObject{
|
|||||||
//获取缓冲值
|
//获取缓冲值
|
||||||
private func cacheLoadTimes() {
|
private func cacheLoadTimes() {
|
||||||
//获取当前播放Item的缓冲值组
|
//获取当前播放Item的缓冲值组
|
||||||
if let timeRanges = loadPlayer.currentVideo?.resourcePlayerItem.loadedTimeRanges.map({$0.timeRangeValue}), let first = timeRanges.first {
|
if let timeRanges = loadPlayer?.currentVideo?.resourcePlayerItem.loadedTimeRanges.map({$0.timeRangeValue}), let first = timeRanges.first {
|
||||||
//获取开始时间的秒数
|
//获取开始时间的秒数
|
||||||
let startSeconds = first.start.seconds
|
let startSeconds = first.start.seconds
|
||||||
//获取缓冲区的持续时间
|
//获取缓冲区的持续时间
|
||||||
|
|||||||
@ -642,12 +642,15 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
}
|
}
|
||||||
struct NavigationEndpoint: Codable {
|
struct NavigationEndpoint: Codable {
|
||||||
let watchEndpoint:WatchEndpoint?
|
let watchEndpoint:WatchEndpoint?
|
||||||
|
let browseEndpoint:BrowseEndpoint?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case watchEndpoint = "watchEndpoint"
|
case watchEndpoint = "watchEndpoint"
|
||||||
|
case browseEndpoint = "browseEndpoint"
|
||||||
}
|
}
|
||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
|
watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
|
||||||
|
browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
|
||||||
}
|
}
|
||||||
struct WatchEndpoint: Codable {
|
struct WatchEndpoint: Codable {
|
||||||
let playlistId:String?
|
let playlistId:String?
|
||||||
@ -659,6 +662,42 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
|
playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
struct BrowseEndpoint: Codable {
|
||||||
|
let browseId:String?
|
||||||
|
let params:String?
|
||||||
|
let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case browseId = "browseId"
|
||||||
|
case params = "params"
|
||||||
|
case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
|
||||||
|
params = try values.decodeIfPresent(String.self, forKey: .params)
|
||||||
|
browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
|
||||||
|
}
|
||||||
|
struct BrowseEndpointContextSupportedConfigs: Codable {
|
||||||
|
let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
|
||||||
|
}
|
||||||
|
struct BrowseEndpointContextMusicConfig: Codable {
|
||||||
|
let pageType:String?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case pageType = "pageType"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -781,6 +820,7 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
|||||||
///当前播放音乐ViewModel
|
///当前播放音乐ViewModel
|
||||||
var currentVideo:MPPositive_SongViewModel!{
|
var currentVideo:MPPositive_SongViewModel!{
|
||||||
willSet{
|
willSet{
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now()) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||||
[weak self] in
|
[weak self] in
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
if newValue != nil {
|
if newValue != nil {
|
||||||
@ -97,6 +97,7 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
|||||||
array = array.filter({!videoIDs.contains($0.videoId)})
|
array = array.filter({!videoIDs.contains($0.videoId)})
|
||||||
|
|
||||||
group = DispatchGroup()
|
group = DispatchGroup()
|
||||||
|
|
||||||
//去重完毕,对剩下内容补完
|
//去重完毕,对剩下内容补完
|
||||||
for item in array {
|
for item in array {
|
||||||
group?.enter()
|
group?.enter()
|
||||||
@ -108,7 +109,7 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
|||||||
self?.group?.leave()
|
self?.group?.leave()
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
group?.leave()
|
self.group?.leave()
|
||||||
}
|
}
|
||||||
group?.enter()
|
group?.enter()
|
||||||
//判断当前videoID是否进行过下载
|
//判断当前videoID是否进行过下载
|
||||||
@ -117,7 +118,7 @@ class MPPositive_PlayerLoadViewModel: NSObject {
|
|||||||
item.resourceUrls = [resource]
|
item.resourceUrls = [resource]
|
||||||
//补全完成,转化为ViewModel,并添加进listViewVideos
|
//补全完成,转化为ViewModel,并添加进listViewVideos
|
||||||
listViewVideos.append(.init(item))
|
listViewVideos.append(.init(item))
|
||||||
group?.leave()
|
self.group?.leave()
|
||||||
}else {
|
}else {
|
||||||
//没有下载过
|
//没有下载过
|
||||||
//补全资源路径组和封面路径组
|
//补全资源路径组和封面路径组
|
||||||
|
|||||||
@ -74,6 +74,7 @@ class MPPositive_MoreSongOperationsViewController: UIViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var removeBlock:(() -> Void)?
|
var removeBlock:(() -> Void)?
|
||||||
|
var disMissBlock:(() -> Void)?
|
||||||
init(_ song:MPPositive_SongItemModel) {
|
init(_ song:MPPositive_SongItemModel) {
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
@ -94,7 +95,12 @@ class MPPositive_MoreSongOperationsViewController: UIViewController {
|
|||||||
view.layer.cornerRadius = 18*width
|
view.layer.cornerRadius = 18*width
|
||||||
configure()
|
configure()
|
||||||
}
|
}
|
||||||
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
|
super.viewWillDisappear(animated)
|
||||||
|
if disMissBlock != nil {
|
||||||
|
disMissBlock!()
|
||||||
|
}
|
||||||
|
}
|
||||||
private func configure() {
|
private func configure() {
|
||||||
view.addSubview(indictorImageView)
|
view.addSubview(indictorImageView)
|
||||||
indictorImageView.snp.makeConstraints { make in
|
indictorImageView.snp.makeConstraints { make in
|
||||||
|
|||||||
@ -93,6 +93,12 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
|
|||||||
[weak self] in
|
[weak self] in
|
||||||
MPPositive_ModalType = .MoreOperations
|
MPPositive_ModalType = .MoreOperations
|
||||||
let moreVC = MPPositive_MoreSongOperationsViewController(first)
|
let moreVC = MPPositive_MoreSongOperationsViewController(first)
|
||||||
|
moreVC.removeBlock = {
|
||||||
|
self?.reload()
|
||||||
|
}
|
||||||
|
moreVC.disMissBlock = {
|
||||||
|
self?.reload()
|
||||||
|
}
|
||||||
moreVC.transitioningDelegate = self
|
moreVC.transitioningDelegate = self
|
||||||
moreVC.modalPresentationStyle = .custom
|
moreVC.modalPresentationStyle = .custom
|
||||||
self?.present(moreVC, animated: true)
|
self?.present(moreVC, animated: true)
|
||||||
|
|||||||
@ -115,6 +115,7 @@ class MPPositive_HomeViewController: MPPositive_BaseViewController{
|
|||||||
}
|
}
|
||||||
removeErrorView()
|
removeErrorView()
|
||||||
MP_HUD.hideNow()
|
MP_HUD.hideNow()
|
||||||
|
tableView.showMessage(MPPositive_BrowseLoadViewModel.shared.browseModuleLists.count)
|
||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -304,18 +304,23 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
|
|||||||
}
|
}
|
||||||
//MARK: - 页面渲染
|
//MARK: - 页面渲染
|
||||||
private func uploadUI() {
|
private func uploadUI() {
|
||||||
//填充数据
|
DispatchQueue.main.async {
|
||||||
backImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl)
|
[weak self] in
|
||||||
coverView.coverImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl)
|
guard let self = self else {return}
|
||||||
coverView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title
|
print("\(MP_PlayerManager.shared.loadPlayer.currentVideo.title ?? "")刷新了页面")
|
||||||
coverView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle
|
//填充数据
|
||||||
lyricsView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title
|
backImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl)
|
||||||
lyricsView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle
|
coverView.coverImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl)
|
||||||
lyricsView.lyricsLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics?.isEmpty == true ? "No Lyrics":MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics
|
coverView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title
|
||||||
coverView.downloadButton.state = (MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false) ? .downloaded:.startDownload
|
coverView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle
|
||||||
coverView.downloadButton.isUserInteractionEnabled = !(MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false)
|
lyricsView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title
|
||||||
coverView.collectionSongBtn.isSelected = MP_PlayerManager.shared.loadPlayer.currentVideo?.isCollection ?? false
|
lyricsView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle
|
||||||
coverView.restoreDownloadProgress()
|
lyricsView.lyricsLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics?.isEmpty == true ? "No Lyrics":MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics
|
||||||
|
coverView.downloadButton.state = (MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", MP_PlayerManager.shared.loadPlayer.currentVideo?.song.videoId ?? "")).count != 0) ? .downloaded:.startDownload
|
||||||
|
coverView.downloadButton.isUserInteractionEnabled = !(MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false)
|
||||||
|
coverView.collectionSongBtn.isSelected = MP_PlayerManager.shared.loadPlayer.currentVideo?.isCollection ?? false
|
||||||
|
coverView.restoreDownloadProgress()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//MARK: - 通知
|
//MARK: - 通知
|
||||||
//播放器音乐刷新
|
//播放器音乐刷新
|
||||||
|
|||||||
@ -22,9 +22,9 @@ class MPPositive_RecommendViewController: MPPositive_BaseViewController,UIViewCo
|
|||||||
[weak self] in
|
[weak self] in
|
||||||
//刷新分页控制器
|
//刷新分页控制器
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
sectionLabel.text = loadRecommend.members.title
|
sectionLabel.text = loadRecommend?.members?.title
|
||||||
collectionView.reloadData()
|
collectionView.reloadData()
|
||||||
dataSource.titles = loadRecommend?.sectionLists.compactMap({$0.title}) ?? []
|
dataSource.titles = loadRecommend?.sectionLists?.compactMap({$0.title}) ?? []
|
||||||
dataSource.reloadData(selectedIndex: 0)
|
dataSource.reloadData(selectedIndex: 0)
|
||||||
segmentView.reloadData()
|
segmentView.reloadData()
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ class MPPositive_RecommendViewController: MPPositive_BaseViewController,UIViewCo
|
|||||||
///音乐人View
|
///音乐人View
|
||||||
private lazy var membersView:UIView = createMusicMembersView()
|
private lazy var membersView:UIView = createMusicMembersView()
|
||||||
//模块标题
|
//模块标题
|
||||||
private lazy var sectionLabel:UILabel = createLabel(font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left)
|
private lazy var sectionLabel:UILabel = createLabel("Loading",font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left)
|
||||||
//音乐人CollectionView
|
//音乐人CollectionView
|
||||||
private lazy var collectionView:UICollectionView = {
|
private lazy var collectionView:UICollectionView = {
|
||||||
let layout = UICollectionViewFlowLayout()
|
let layout = UICollectionViewFlowLayout()
|
||||||
|
|||||||
@ -131,8 +131,8 @@ class MPPositive_PlayerCoverView: UIView, PKDownloadButtonDelegate {
|
|||||||
downloadButton.stopDownloadButton.progress = progress
|
downloadButton.stopDownloadButton.progress = progress
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
//不是正在下载的内容
|
//不是正在下载的内容,判断是否下载了
|
||||||
downloadButton.state = .startDownload
|
downloadButton.state = (MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", currentVideo.song.videoId ?? "")).count != 0) ? .downloaded:.startDownload
|
||||||
downloadButton.isUserInteractionEnabled = true
|
downloadButton.isUserInteractionEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,8 +90,8 @@
|
|||||||
<color key="textColor" white="1" alpha="0.40000000000000002" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="textColor" white="1" alpha="0.40000000000000002" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Version 1.0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="miJ-lx-eHK">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Version 1.0.2" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="miJ-lx-eHK">
|
||||||
<rect key="frame" x="294" y="22" width="66" height="16"/>
|
<rect key="frame" x="283" y="22" width="77" height="16"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||||
<color key="textColor" red="0.61960784310000006" green="0.61960784310000006" blue="0.61960784310000006" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.61960784310000006" green="0.61960784310000006" blue="0.61960784310000006" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user