AutoSaveManager.swift 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. //
  2. // AutoSaveManager.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2023/11/8.
  6. //
  7. import Cocoa
  8. public let KAutoSaveTimeValueChangedNoti = "KAutoSaveTimeValueChangedNoti"
  9. class AutoSaveManager: NSObject {
  10. //APP是否允许进行自动缓存
  11. var autoSaveEnabled = false {
  12. didSet {
  13. UserDefaults.standard.setValue(self.autoSaveEnabled, forKey: "ComAutoSaveKey")
  14. UserDefaults.standard.synchronize()
  15. }
  16. }
  17. var timeInterval: CGFloat = 15 {
  18. didSet {
  19. UserDefaults.standard.setValue(Float(self.timeInterval), forKey: "AutoSaveTimeIntervalKey")
  20. UserDefaults.standard.synchronize()
  21. }
  22. }
  23. //防止重复弹出
  24. var autoSaveAlertShow = false
  25. var autoSaveDidEndAction = false
  26. // /当前是否正在保存
  27. var isSaving = false
  28. private var _autoSaveFolder: String = ""
  29. var autoSaveFolder: String {
  30. get {
  31. return self._autoSaveFolder
  32. }
  33. }
  34. private var _infoDict: NSMutableDictionary?
  35. // 保存的原文件信息
  36. private var _originalPaths: NSMutableArray?
  37. var originalPaths: NSMutableArray? {
  38. get {
  39. return self._originalPaths
  40. }
  41. }
  42. // 对应保存的信息
  43. private var _autoSavePaths: NSMutableArray?
  44. var autoSavePaths: NSMutableArray? {
  45. get {
  46. return self._autoSavePaths
  47. }
  48. }
  49. // 所有打开的文件信息汇总
  50. private var _opendPaths: NSMutableArray?
  51. static let manager: AutoSaveManager = {
  52. let man = AutoSaveManager()
  53. man.autoSaveEnabled = UserDefaults.standard.bool(forKey: "ComAutoSaveKey")
  54. let timeInterval = UserDefaults.standard.float(forKey: "AutoSaveTimeIntervalKey")
  55. if timeInterval > 0 {
  56. man.timeInterval = timeInterval.cgFloat
  57. } else {
  58. man.timeInterval = 15
  59. }
  60. man._loadData()
  61. man.autoSaveDidEndAction = true
  62. return man
  63. }()
  64. // MARK: - Public Method
  65. func clearCache() {
  66. if FileManager.default.fileExists(atPath: self.autoSaveFolder) {
  67. try?FileManager.default.removeItem(atPath: self.autoSaveFolder)
  68. }
  69. if FileManager.default.fileExists(atPath: self.autoSaveFolder) == false {
  70. try?FileManager.default.createDirectory(atPath: self.autoSaveFolder, withIntermediateDirectories: true)
  71. }
  72. }
  73. func autoSaveWithPath(_ filePath: String) -> String {
  74. let autoSaveFolder = self.autoSaveFolder
  75. let plistPath = String(format: "%@/autoSaveInfo.plist", autoSaveFolder)
  76. var savePath = String(format: "%@/%@_%@.%@", autoSaveFolder, filePath.deletingPathExtension.lastPathComponent, "recovered", filePath.customPathExtension)
  77. if FileManager.default.fileExists(atPath: plistPath) {
  78. var dict = NSMutableDictionary(contentsOfFile: plistPath)
  79. if let keys = dict?.allKeys as? [String], keys.contains(filePath) {
  80. savePath = dict?.value(forKey: filePath) as? String ?? ""
  81. }
  82. if savePath.isEmpty == false && filePath.isEmpty == false {
  83. if let values = dict?.allValues as? [String], values.contains(savePath) {
  84. //不同路径下同名文件的保存覆盖的情况处理
  85. var values = NSArray(array: values)
  86. for key in dict?.allKeys ?? [] {
  87. guard let _key = key as? String else {
  88. continue
  89. }
  90. let value = dict?.object(forKey: key) as? String ?? ""
  91. if savePath == value && _key != filePath {
  92. var count = 1
  93. savePath = String(format: "%@/%@_%@(%d).%@", autoSaveFolder, filePath.deletingPathExtension.lastPathComponent, "recovered", count, filePath.customPathExtension)
  94. while values.contains(savePath) {
  95. count += 1
  96. savePath = String(format: "%@/%@_%@(%d).%@", autoSaveFolder, filePath.deletingPathExtension.lastPathComponent, "recovered", count, filePath.customPathExtension)
  97. }
  98. }
  99. }
  100. }
  101. dict?.setValue(savePath, forKey: filePath)
  102. }
  103. try?dict?.write(to: URL(fileURLWithPath: plistPath))
  104. } else {
  105. var dict = NSMutableDictionary()
  106. if savePath.isEmpty == false && filePath.isEmpty == false {
  107. dict.setValue(savePath, forKey: filePath)
  108. }
  109. try?dict.write(to: URL(fileURLWithPath: plistPath))
  110. }
  111. return savePath
  112. }
  113. func removeAutoSavePath(_ filePath: String) {
  114. let autoSaveFolder = self.autoSaveFolder
  115. let plistPath = String(format: "%@/autoSaveInfo.plist", autoSaveFolder)
  116. if FileManager.default.fileExists(atPath: plistPath) {
  117. var dict = NSMutableDictionary(contentsOfFile: plistPath)
  118. if let savePath = dict?.value(forKey: filePath) as? String {
  119. if FileManager.default.fileExists(atPath: savePath) {
  120. try?FileManager.default.removeItem(atPath: savePath)
  121. }
  122. dict?.removeObject(forKey: filePath)
  123. }
  124. if let keys = dict?.allKeys, keys.count > 0 {
  125. try?dict?.write(to: URL(fileURLWithPath: plistPath))
  126. } else {
  127. try?FileManager.default.removeItem(atPath: plistPath)
  128. }
  129. }
  130. }
  131. // MARK: - Private Methods
  132. private func _loadData() {
  133. var cachesPath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first ?? ""
  134. let filepath = "\(cachesPath)/\(Bundle.main.bundleIdentifier ?? "")"
  135. if FileManager.default.fileExists(atPath: filepath) {
  136. cachesPath = filepath
  137. }
  138. cachesPath = "\(cachesPath)/autoSaveFolder"
  139. if FileManager.default.fileExists(atPath: cachesPath) == false {
  140. try?FileManager.default.createDirectory(atPath: cachesPath, withIntermediateDirectories: true)
  141. }
  142. self._autoSaveFolder = cachesPath
  143. KMPrint("autoSaveFolder===\(cachesPath)")
  144. let plistPath = String(format: "%@/autoSaveInfo.plist", self.autoSaveFolder)
  145. guard let dict = NSMutableDictionary(contentsOfFile: plistPath) else {
  146. return
  147. }
  148. if (dict.allKeys.count == 0) {
  149. return
  150. }
  151. self._infoDict = dict
  152. if (self._autoSavePaths == nil) {
  153. self._autoSavePaths = NSMutableArray()
  154. }
  155. if (self._originalPaths == nil) {
  156. self._originalPaths = NSMutableArray()
  157. }
  158. self._originalPaths?.addObjects(from: dict.allKeys)
  159. self._opendPaths = NSMutableArray()
  160. var arr = (try?FileManager.default.contentsOfDirectory(atPath: self.autoSaveFolder)) ?? []
  161. for fileName in arr {
  162. let savedKey = "\(self.autoSaveFolder)/\(fileName)"
  163. guard let values = dict.allValues as? [String] else {
  164. continue
  165. }
  166. if values.contains(savedKey) {
  167. self.autoSavePaths?.add(savedKey)
  168. } else {
  169. if fileName == "autoSaveInfo.plist" {
  170. } else {
  171. try?FileManager.default.removeItem(atPath: savedKey)
  172. }
  173. }
  174. }
  175. }
  176. /*
  177. - (NSString *)URLEncodedString:(NSString *)string {
  178. CFStringRef stringRef = CFBridgingRetain(string);
  179. #pragma clang diagnostic push
  180. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  181. CFStringRef encoded = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
  182. stringRef,
  183. NULL,
  184. CFSTR("!*'\"();:@&=+$,/?%#[]% "),
  185. kCFStringEncodingUTF8);
  186. #pragma clang diagnostic pop
  187. CFRelease(stringRef);
  188. return CFBridgingRelease(encoded);
  189. }
  190. - (NSString *)getValidFilePath:(NSString *)oldPath {
  191. NSFileManager *fileManager = [NSFileManager defaultManager];
  192. NSDictionary *fileDic = [fileManager attributesOfItemAtPath:oldPath error:nil];
  193. NSString *fileType = [fileDic objectForKey:NSFileType];
  194. int i =1;
  195. NSString *newPath = oldPath;
  196. while ([fileManager fileExistsAtPath:newPath]) {
  197. if ([fileType isEqualToString:NSFileTypeDirectory]) {
  198. newPath = [oldPath stringByAppendingFormat:@"(%d)",i];
  199. } else {
  200. NSString *fileExtension = [oldPath pathExtension];
  201. newPath = [[oldPath stringByDeletingPathExtension] stringByAppendingFormat:@"(%d).%@",i,fileExtension];
  202. }
  203. i++;
  204. }
  205. return newPath;
  206. }
  207. */
  208. }