TSCommonTool.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. //
  2. // TSCommonTool.swift
  3. // TSLiveWallpaper
  4. //
  5. // Created by 100Years on 2024/12/20.
  6. //
  7. import Kingfisher
  8. import Foundation
  9. import AVFoundation
  10. class TSCommonTool {
  11. //
  12. // static func downLoadImage(_ urlStr:String, completion: @escaping (_ image:UIImage) -> Void) {
  13. // ImageDownloader.default.downloadImage(with: URL(string: urlStr)!, options: nil) { receivedSize, totalSize in
  14. // debugPrint(receivedSize)
  15. // } completionHandler: {
  16. // result in
  17. // switch result {
  18. // case .success(let value):
  19. // completion(value.image)
  20. // case .failure(let error):
  21. // print(error)
  22. // }
  23. // }
  24. // }
  25. //
  26. /// 下载图片,优先从缓存中取,支持设置缓存策略
  27. /// - Parameters:
  28. /// - url: 图片的 URL 地址
  29. /// - completion: 完成回调,返回图片或错误
  30. static func fetchImageWithCache(
  31. from urlString: String,
  32. completion: @escaping (UIImage?, Error?) -> Void
  33. ) {
  34. guard let url = URL(string: urlString) else{
  35. completion(nil, NSError(domain: "url null", code: 0))
  36. return
  37. }
  38. // 配置 Kingfisher 的缓存策略
  39. let options: KingfisherOptionsInfo = [
  40. .cacheOriginalImage,
  41. .memoryCacheExpiration(.days(7)), // 内存缓存时间
  42. .diskCacheExpiration(.days(30)), // 磁盘缓存时间
  43. .cacheSerializer(DefaultCacheSerializer.default)
  44. ]
  45. // 使用 Kingfisher 检查缓存是否存在
  46. let cache = ImageCache.default
  47. let cacheKey = url.absoluteString
  48. cache.retrieveImage(forKey: cacheKey, options: nil) { result in
  49. switch result {
  50. case .success(let value):
  51. if let image = value.image {
  52. // 从缓存中取到图片
  53. completion(image, nil)
  54. } else {
  55. // 缓存中不存在图片,进行下载
  56. downloadImage(from: url, options: options, completion: completion)
  57. }
  58. case .failure(let error):
  59. // 缓存检查失败,直接下载
  60. print("缓存检查失败: \(error.localizedDescription)")
  61. downloadImage(from: url, options: options, completion: completion)
  62. }
  63. }
  64. }
  65. /// 获取已缓存的磁盘图片文件路径
  66. /// - Parameters:
  67. /// - urlString: 图片的 URL 地址
  68. /// - completion: 完成回调,返回图片的磁盘路径或错误
  69. static func fetchImagePathWithCache(
  70. from urlString: String,
  71. completion: @escaping (String?, Error?) -> Void
  72. ) {
  73. guard let url = URL(string: urlString) else {
  74. completion(nil, NSError(domain: "InvalidURL", code: 0, userInfo: [NSLocalizedDescriptionKey: "无效的 URL"]))
  75. return
  76. }
  77. let cache = ImageCache.default
  78. let cacheKey = url.absoluteString
  79. if cache.isCached(forKey: cacheKey) {
  80. completion(cache.cachePath(forKey: cacheKey), nil)
  81. }else {
  82. completion(nil, NSError(domain: "CachePathError", code: 1, userInfo: [NSLocalizedDescriptionKey: "无法获取缓存路径"]))
  83. }
  84. }
  85. /// 下载图片并缓存
  86. /// - Parameters:
  87. /// - url: 图片的 URL 地址
  88. /// - options: Kingfisher 下载和缓存的选项
  89. /// - completion: 完成回调,返回图片或错误
  90. static func downloadImage(
  91. from url: URL,
  92. options: KingfisherOptionsInfo,
  93. completion: @escaping (UIImage?, Error?) -> Void
  94. ) {
  95. KingfisherManager.shared.retrieveImage(with: url, options: options,progressBlock: { receivedSize, totalSize in
  96. debugPrint(receivedSize)
  97. }) { result in
  98. switch result {
  99. case .success(let value):
  100. completion(value.image, nil)
  101. case .failure(let error):
  102. completion(nil, error)
  103. }
  104. }
  105. }
  106. /// 下载并缓存文件,依据 URL 的后缀名动态设置文件名
  107. /// - Parameters:
  108. /// - url: 文件的 URL 地址
  109. /// - completion: 完成回调,返回本地缓存路径或错误
  110. static func downloadAndCacheFile(from urlString: String, fileEx:String? = nil, cacheDirectory:String = "cacheVideo",completion: @escaping (String?, Error?) -> Void) {
  111. guard let url = URL(string: urlString) else{
  112. completion(nil, NSError(domain: "url null", code: 0))
  113. return
  114. }
  115. if !urlString.contains("http") && urlString.contains("/"){
  116. completion(urlString.fillCachePath, nil)
  117. return
  118. }
  119. let fileManager = FileManager.default
  120. // 获取缓存目录下的 `cacheVideo` 文件夹路径
  121. let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
  122. let cacheVideoDirectory = cacheDirectory.appendingPathComponent("cacheVideo")
  123. // 创建 `cacheVideo` 文件夹(如果不存在)
  124. if !fileManager.fileExists(atPath: cacheVideoDirectory.path) {
  125. do {
  126. try fileManager.createDirectory(at: cacheVideoDirectory, withIntermediateDirectories: true, attributes: nil)
  127. } catch {
  128. completion(nil, error)
  129. return
  130. }
  131. }
  132. // 使用 URL 的 MD5 哈希值作为缓存文件名,附加 URL 的后缀名
  133. var fileExtension = fileEx
  134. fileExtension = fileExtension ?? (url.pathExtension.isEmpty ? "tmp" : url.pathExtension)
  135. let fileName = url.path.md5 + ".\(fileExtension!)"
  136. let cachedFileURL = cacheVideoDirectory.appendingPathComponent(fileName)
  137. // 检查文件是否已存在于缓存中
  138. if fileManager.fileExists(atPath: cachedFileURL.path) {
  139. print("文件已存在于缓存中: \(cachedFileURL)")
  140. completion(cachedFileURL.path, nil)
  141. return
  142. }
  143. // 下载文件
  144. let task = URLSession.shared.downloadTask(with: url) { tempFileURL, response, error in
  145. if let error = error {
  146. completion(nil, error)
  147. return
  148. }
  149. guard let tempFileURL = tempFileURL else {
  150. completion(nil, NSError(domain: "DownloadError", code: -1, userInfo: [NSLocalizedDescriptionKey: "临时文件路径不存在"]))
  151. return
  152. }
  153. do {
  154. try fileManager.moveItem(at: tempFileURL, to: cachedFileURL)
  155. print("文件下载并缓存成功: \(cachedFileURL)")
  156. completion(cachedFileURL.path, nil)
  157. } catch {
  158. completion(nil, error)
  159. }
  160. }
  161. task.resume()
  162. }
  163. }
  164. let kMainQueue = DispatchQueue.main
  165. let appid = "6740220736"
  166. let kAppName:String = "Picguru" //Picguru Chibii Chibi Ghiblii AI Image Picguru
  167. let kUploadImageMaxBit10Size:Int = 10 * 1024 * 1024 //10M
  168. let kUploadImageMaxBit5Size:Int = 5 * 1024 * 1024 //5M
  169. func kShareContent(target: UIViewController,anyData:Any) {
  170. let text = "Turn yourself into a Ghibli style with AI magic! 🎨✨ This app creates stunning anime, cyberpunk & more—just upload a photo. Try it now!"
  171. kShareContent(target: target, anyData: anyData, text: text)
  172. // shareApplication(target: target)
  173. }
  174. //func kShareContent(target: UIViewController,image:UIImage?,text:String?) {
  175. //
  176. // let url = URL(string: "https://apps.apple.com/app/id\(appid)")
  177. //
  178. // let provider = CustomActivityItemProvider(image: image, text: text, url: url)
  179. // let vc = UIActivityViewController(activityItems: [provider], applicationActivities: nil)
  180. // vc.completionWithItemsHandler = { activity, _, _, _ in
  181. // switch activity {
  182. // case .copyToPasteboard:
  183. // UIPasteboard.general.string = text
  184. // default:
  185. // dePrint("")
  186. // }
  187. //// if let type = activity, type == .copyToPasteboard {
  188. //// UIPasteboard.general.string = text
  189. //// }else
  190. // }
  191. //
  192. // if UIDevice.current.userInterfaceIdiom == .pad {
  193. // vc.modalPresentationStyle = .popover
  194. // vc.popoverPresentationController?.sourceView = target.view
  195. // vc.popoverPresentationController?.sourceRect = target.view.bounds
  196. // }
  197. //
  198. // target.present(vc, animated: true)
  199. //}
  200. func kShareContent(target: UIViewController,anyData:Any?,text:String?) {
  201. //
  202. // let url = URL(string: "https://apps.apple.com/app/id\(appid)")
  203. // ShareHelper.share(
  204. // image: image,
  205. // text: text,
  206. // url: url,
  207. // from: target,
  208. // sourceView: target.view // 可以是按钮或其他UIView
  209. // )
  210. // return
  211. let urlString = "https://apps.apple.com/app/id\(appid)"
  212. var activityItems:[Any] = []
  213. if let anyData = anyData {
  214. activityItems.append(anyData)
  215. }
  216. if let text = text {
  217. activityItems.append(text+"\nApp:"+urlString)
  218. }
  219. // if let url = URL(string: "https://apps.apple.com/app/id\(appid)") {
  220. // activityItems.append(url)
  221. // }
  222. if activityItems.isEmpty {
  223. return
  224. }
  225. let vc = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
  226. vc.completionWithItemsHandler = { activity, _, _, _ in
  227. switch activity {
  228. case .copyToPasteboard:
  229. UIPasteboard.general.string = text
  230. default:
  231. dePrint("")
  232. }
  233. }
  234. if UIDevice.current.userInterfaceIdiom == .pad {
  235. vc.modalPresentationStyle = .popover
  236. vc.popoverPresentationController?.sourceView = target.view
  237. vc.popoverPresentationController?.sourceRect = target.view.bounds
  238. }
  239. target.present(vc, animated: true)
  240. }
  241. //func shareApplication(target: UIViewController) {
  242. // let text = "I'm using Sweeter to decorate my phone, there are not only themes, wallpapers, widgets, but also dynamic island and super useful tools, come and try with me!"
  243. // let httpAppStoreLink = "https://apps.apple.com/app/id\(appid)"
  244. // let url = URL(string: httpAppStoreLink)!
  245. // let image = UIImage(named: "App-Icon")!.compressImageSize(to: CGSize(width: 100, height: 100))
  246. // let vc = UIActivityViewController(activityItems: [image, text, url], applicationActivities: nil)
  247. // vc.completionWithItemsHandler = { activity, value, _, error in
  248. // if let type = activity, type == .copyToPasteboard {
  249. // UIPasteboard.general.string = httpAppStoreLink
  250. // }
  251. // }
  252. // if UIDevice.current.userInterfaceIdiom == .pad {
  253. // vc.modalPresentationStyle = .popover
  254. // vc.popoverPresentationController?.sourceView = target.view
  255. // vc.popoverPresentationController?.sourceRect = target.view.bounds
  256. // }
  257. // target.present(vc, animated: true)
  258. //}
  259. //// todo.kailen-logo
  260. //func shareApp(parent: UIViewController) {
  261. // let httpAppStoreLink = "https://apps.apple.com/app/id\(appid)"
  262. // let text = "Space"
  263. // let url = URL(string: httpAppStoreLink)!
  264. // let image = UIImage.appIcon.compressImageSize(to: CGSize(width: 100, height: 100))
  265. // let final = ShareActivityItemProvider(placeholderItem: image)
  266. // let vc = UIActivityViewController(activityItems: [url, final, text], applicationActivities: nil)
  267. // vc.completionWithItemsHandler = { activity, _, _, _ in
  268. // if let type = activity, type == .copyToPasteboard {
  269. // UIPasteboard.general.string = httpAppStoreLink
  270. // }
  271. // }
  272. //
  273. // parent.present(vc, animated: true)
  274. //
  275. //}