201 lines
6.2 KiB
Swift
201 lines
6.2 KiB
Swift
//
|
||
// Tools.swift
|
||
// Crush
|
||
//
|
||
// Created by Leon on 2025/7/12.
|
||
//
|
||
|
||
import Foundation
|
||
import AdSupport
|
||
import AppTrackingTransparency
|
||
|
||
/// 常用工具和常用字典。
|
||
class CLTool {
|
||
static let shared = CLTool()
|
||
|
||
var appVersion: AppVersion?
|
||
|
||
static func clearTempFolder() {
|
||
let fileManager = FileManager.default
|
||
let tempFolderPath = NSTemporaryDirectory()
|
||
|
||
do {
|
||
let filePaths = try fileManager.contentsOfDirectory(atPath: tempFolderPath)
|
||
for filePath in filePaths {
|
||
// dlog("filaPath: \(filePath)")
|
||
try fileManager.removeItem(atPath: NSTemporaryDirectory() + filePath)
|
||
}
|
||
} catch let error as NSError {
|
||
print("Could not clear temp folder: \(error.debugDescription)")
|
||
}
|
||
}
|
||
|
||
static func feedbackGenerator() {
|
||
if #available(iOS 13.0, *) {
|
||
let gen = UIImpactFeedbackGenerator(style: .medium) // light震动效果的强弱
|
||
gen.prepare() // 反馈延迟最小化
|
||
gen.impactOccurred() // 触发效果
|
||
}
|
||
}
|
||
|
||
static func syncInputTintColor() {
|
||
UITextField.appearance().tintColor = .blue
|
||
UITextView.appearance().tintColor = .blue
|
||
}
|
||
|
||
// MARK: - public
|
||
|
||
public func requestAppVersion(block: ((_ appVer: AppVersion?) -> Void)?) {
|
||
if let appVer = appVersion {
|
||
block?(appVer)
|
||
return
|
||
}
|
||
|
||
// CommonProvider.request(.appVersionGet, modelType: AppVersion.self, autoShowErrMsg: false) { [weak self] result in
|
||
// switch result {
|
||
// case let .success(model):
|
||
// self?.appVersion = model
|
||
// block?(model)
|
||
// break
|
||
// case .failure:
|
||
// break
|
||
// }
|
||
// }
|
||
}
|
||
|
||
public func findLocaliezedNameBy(code: String) -> String? {
|
||
// for per in langNameCodes {
|
||
// if per.langCode == code {
|
||
// return per.codeName
|
||
// }
|
||
// }
|
||
|
||
return nil
|
||
}
|
||
|
||
static func syncSystemLanguage() {
|
||
}
|
||
|
||
/// 多语言适配
|
||
static func syncAppLanuage(lan: Languages, completion: ((_ result: Bool) -> Void)?) {
|
||
// MeProvider.request(.updateLanguage(lang: lan.rawValue), modelType: String.self, autoShowErrMsg: false) { result in
|
||
// switch result {
|
||
// case .success:
|
||
// completion?(true)
|
||
// break
|
||
// case .failure:
|
||
// completion?(false)
|
||
// break
|
||
// }
|
||
// }
|
||
}
|
||
|
||
/// 通过regionCode来决定国家显示名称
|
||
static func getLocalizedCountryName(localeIdentifier: String?) -> String {
|
||
guard let identi = localeIdentifier else { return "" }
|
||
|
||
var regionCode = "en"
|
||
|
||
// 获取设备的国家Code
|
||
if let currentRegionCode = Locale.current.regionCode {
|
||
regionCode = currentRegionCode
|
||
}
|
||
|
||
let locale = Locale(identifier: regionCode)
|
||
if let localisedCountryName = locale.localizedString(forRegionCode: identi) {
|
||
return localisedCountryName
|
||
} else {
|
||
dlog("⚠️无法localize国家:\(identi)")
|
||
return ""
|
||
}
|
||
}
|
||
|
||
static func getLocalizedCountryNameByPreferLan(localeIdentifier: String?) -> String {
|
||
guard let identi = localeIdentifier else { return "" }
|
||
|
||
guard let lan = Languages.preferedLans.first else { return "" }
|
||
let locale = Locale(identifier: Languages.regionCode(lan: lan))
|
||
|
||
if let localisedCountryName = locale.localizedString(forRegionCode: identi) {
|
||
return localisedCountryName
|
||
} else {
|
||
dlog("Languages Prefer lan 's locale country name get failed ❌:\(identi) 采用备选方案根据Locale.current来获取")
|
||
return getLocalizedCountryName(localeIdentifier: localeIdentifier)
|
||
}
|
||
}
|
||
|
||
// MARK: - helper.
|
||
}
|
||
|
||
extension CLTool {
|
||
static func idfaSetupReport() {
|
||
if #available(iOS 14, *) {
|
||
ATTrackingManager.requestTrackingAuthorization { status in
|
||
switch status {
|
||
case .denied:
|
||
debugPrint("【IDFA】用户拒绝")
|
||
break
|
||
case .authorized:
|
||
debugPrint("【IDFA】用户允许:❇️IDFA: \(ASIdentifierManager.shared().advertisingIdentifier.uuidString)❇️")
|
||
CLTool.tryReportIDFA()
|
||
break
|
||
case .notDetermined:
|
||
debugPrint("【IDFA】用户没有选择")
|
||
default:
|
||
break
|
||
}
|
||
}
|
||
} else {
|
||
// iOS13及之前版本,继续用以前的方式
|
||
if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
|
||
// debugPrint("可以获取:\(ASIdentifierManager.shared().advertisingIdentifier.uuidString)")
|
||
CLTool.tryReportIDFA()
|
||
} else {
|
||
debugPrint("【IDFA】用户未打开IDFA开关")
|
||
}
|
||
}
|
||
}
|
||
|
||
fileprivate static func tryReportIDFA() {
|
||
let str = ASIdentifierManager.shared().advertisingIdentifier.uuidString
|
||
if str.contains("0000-0000-0000") || str.count == 0 {
|
||
return
|
||
}
|
||
|
||
if let isSubmmited = AppCache.fetchCache(key: CacheKey.boolIdfaSubmmited.rawValue, type: Bool.self), isSubmmited == true {
|
||
return
|
||
}
|
||
|
||
// ComplexProvider.request(.reportIDFA(str: str), modelType: String.self, autoShowErrMsg: false) { result in
|
||
// switch result {
|
||
// case let .success(model):
|
||
// dlog(model)
|
||
// AppCache.cache(key: CacheKey.boolIdfaSubmmited.rawValue, value: true)
|
||
// break
|
||
// case .failure:
|
||
// break
|
||
// }
|
||
// }
|
||
}
|
||
}
|
||
|
||
// MARK: Sandbox
|
||
|
||
extension CLTool{
|
||
static func m4aFileToBase64(fileURL: URL?) -> String? {
|
||
guard let fileURL = fileURL else {
|
||
dlog("文件 URL 为空")
|
||
return nil
|
||
}
|
||
|
||
do {
|
||
let data = try Data(contentsOf: fileURL)
|
||
let base64String = data.base64EncodedString()
|
||
return base64String
|
||
} catch {
|
||
dlog("读取或转换失败: \(error)")
|
||
return nil
|
||
}
|
||
}
|
||
}
|