ASGenerateBaseOperation.swift 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. //
  2. // ASGenerateBaseOperation.swift
  3. // AIPlayRingtones
  4. //
  5. // Created by 100Years on 2025/5/16.
  6. //
  7. import Combine
  8. import Alamofire
  9. class ASGenerateBaseOperationQueue: ASBaseOperationQueue {
  10. // 存储每个操作的 AnyCancellable
  11. var stateables: [String: AnyCancellable] = [:]
  12. var generateOperationStateChanged:((String)->Void)?
  13. override func cancelOperations(uuid: String) {
  14. super.cancelOperations(uuid: uuid)
  15. stateables.removeValue(forKey: uuid)
  16. }
  17. func handleStateDatauPblished(uuid:String,generateOperation: ASGenerateBaseOperation,notificationName:Notification.Name) {
  18. stateables[uuid] = generateOperation.$stateDatauPblished.sink { [weak self] state in
  19. guard let self = self else { return }
  20. DispatchQueue.main.async {
  21. self.generateOperationStateChanged?(uuid)
  22. let uuidData = self.getUUIDData(uuid: uuid)
  23. NotificationCenter.default.post(
  24. name: notificationName,
  25. object: nil,
  26. userInfo: [
  27. "uuid": uuid,
  28. "count":self.queue.maxConcurrentOperationCount,
  29. "state":uuidData.0,
  30. "actionInfo":uuidData.1,
  31. ])
  32. }
  33. }
  34. }
  35. func getUUIDData(uuid:String)->(ASProgressState,ASActionInfoModel?){
  36. return (.none,ASActionInfoModel())
  37. }
  38. }
  39. class ASGenerateBaseOperation: ASBaseOperation , @unchecked Sendable{
  40. var actionInfoDict:[String:Any]{
  41. return [:]
  42. }
  43. @Published var stateDatauPblished:(ASProgressState,ASActionInfoModel?) = (ASProgressState.none,nil){
  44. didSet{
  45. // logPrint("ASBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
  46. // if let block = self.stateDataPblishedChanged{
  47. // logPrint("刷新进度block 真=\(self.stateDatauPblished)")
  48. // self.stateDataPblishedChanged?(self.stateDatauPblished.0,self.stateDatauPblished.1)
  49. // }else{
  50. // logPrint("刷新进度block 空=\(self.stateDatauPblished)")
  51. // }
  52. DispatchQueue.main.async {
  53. self.stateDataPblishedChanged?(self.stateDatauPblished.0,self.stateDatauPblished.1)
  54. }
  55. if case .start = stateDatauPblished.0 {
  56. start()
  57. }else if stateDatauPblished.0.isResult {
  58. DispatchQueue.main.asyncAfter(deadline: .now()+0.3){//稍微延迟,让通知报成功状态发送出去
  59. self.finished()
  60. }
  61. }
  62. }
  63. }
  64. var queryRequest:Request?
  65. var stopNetwork = false
  66. var generatingProgress = 0
  67. var action_id:Int = 0
  68. var isSaveProcessToDB:Bool = false //是否保存过程到数据库
  69. {
  70. didSet{
  71. if isSaveProcessToDB == true {
  72. saveDataDB()
  73. }
  74. }
  75. }
  76. var currentActionInfoModelChanged:((ASActionInfoModel)->Void)?
  77. var stateDataPblishedChanged:((ASProgressState,ASActionInfoModel?)->Void)?
  78. @Published var currentActionInfoModel: ASActionInfoModel = ASActionInfoModel()
  79. func initializeActionInfoModel(oldModel:ASActionInfoModel) {
  80. currentActionInfoModel = oldModel
  81. replaceSaveInfoModel(model: currentActionInfoModel)
  82. stateDatauPblished = (.start,currentActionInfoModel)
  83. }
  84. func replaceSaveInfoModel(model:ASActionInfoModel){ }
  85. func handleGenerateSuccess(){}
  86. func saveDataDB(){}
  87. func backstageGeneration(){}
  88. func handleFailInfoModel(errorString:String?,code:Int = 0){
  89. self.currentActionInfoModel.actionStatus = .failed
  90. self.currentActionInfoModel.status = "failed"
  91. generatingProgress = 0
  92. self.replaceSaveInfoModel(model: self.currentActionInfoModel)
  93. self.stateDatauPblished = (ASProgressState.getFailed(errorString ?? "",code),self.currentActionInfoModel)
  94. }
  95. func getActionInfo(oldModel:ASActionInfoModel) {
  96. currentActionInfoModel = oldModel
  97. self.getActionInfo(action_id:oldModel.id)
  98. }
  99. func getActionInfo(action_id:Int){
  100. self.action_id = action_id
  101. queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
  102. guard let self = self else { return }
  103. if stopNetwork == true {
  104. return
  105. }
  106. if let error = error {
  107. logPrint("getActionInfo error error = \(error)")
  108. handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
  109. return
  110. }
  111. if let result = kNetWorkResultSuccess(data: data) {
  112. if let genmojiModel = ASActionInfoModel(JSON: result) {
  113. if genmojiModel.actionStatus != .success {
  114. self.replaceSaveInfoModel(model: genmojiModel)
  115. }
  116. switch genmojiModel.actionStatus {
  117. case .success:
  118. let successBlock = { [weak self] in
  119. guard let self = self else { return }
  120. self.replaceSaveInfoModel(model: genmojiModel)
  121. self.stateDatauPblished = (.success(nil),genmojiModel)
  122. generatingProgress = 0
  123. self.handleGenerateSuccess()
  124. }
  125. if URL(string:genmojiModel.response.musicUrl) != nil {
  126. ASDownloadManager.getDownLoadRing(urlString: genmojiModel.response.musicUrl) { [weak self] progress in
  127. guard let self = self else { return }
  128. let progressInt = Int(progress*10.0)
  129. let progressString = "Generating".localized + " \(90 + progressInt)%"
  130. stateDatauPblished = (.progress(kPercentScale+Float(progress)*0.1,progressString),currentActionInfoModel)
  131. logPrint("生成后下载进度 \(progress)")
  132. } complete: { [weak self] url, success in
  133. guard let self = self else { return }
  134. if let url = url {
  135. genmojiModel.ringSavePath = url.path.documentLastURL
  136. if let info = TSBusinessAudioPlayer.getAudioFileInfo(path: url.path) {
  137. if let duration = info.durationInSeconds {
  138. genmojiModel.response.duration = Int(duration)
  139. }
  140. if let size = info.sizeInBytes {
  141. genmojiModel.response.size = Int(size)
  142. }
  143. }
  144. successBlock()
  145. }else{
  146. self.handleFailInfoModel(errorString: nil)
  147. }
  148. }
  149. }else{
  150. successBlock()
  151. }
  152. case .failed:
  153. logPrint("getActionInfo error failed")
  154. handleFailInfoModel(errorString:genmojiModel.response.codeErrorMsg,code: genmojiModel.response.code)
  155. default:
  156. let progressText = generating(progress: genmojiModel.percent)
  157. stateDatauPblished = (.progress(genmojiModel.percent*kPercentScale,progressText),currentActionInfoModel)
  158. if stopNetwork == false {
  159. kDelayOnMainThread(2.0) {
  160. self.getActionInfo(action_id: action_id)
  161. }
  162. }
  163. }
  164. return
  165. }
  166. }
  167. logPrint("getActionInfo error nil")
  168. handleFailInfoModel(errorString: nil)
  169. }
  170. }
  171. func generating(progress:Float) -> String {
  172. //Generating 0%-100%
  173. var progressInt = Int(progress*100)
  174. if generatingProgress >= progressInt{
  175. return getGeneratingProgressText()
  176. }
  177. if progressInt > 99 {
  178. progressInt = 99
  179. }
  180. generatingProgress = progressInt
  181. return getGeneratingProgressText()
  182. }
  183. func getGeneratingProgressText()->String{
  184. return "Working on your ringtone \(generatingProgress)%..."
  185. }
  186. override func cancelCleanContent() {
  187. logPrint("cancelCleanContent")
  188. stopNetwork = true
  189. queryRequest?.cancel()
  190. }
  191. }
  192. let kPercentScale:Float = 0.9 //下载进度的缩减比例
  193. var kRandomBoolLastResult:Bool = true
  194. func kRandomBool() -> Bool {
  195. if !kRandomBoolLastResult {
  196. // 如果上一次是 false,这次必须返回 true
  197. kRandomBoolLastResult = true
  198. return true
  199. } else {
  200. // 如果上一次是 true,随机返回 true 或 false
  201. let randomResult = Bool.random()
  202. kRandomBoolLastResult = randomResult
  203. return randomResult
  204. }
  205. }