KMDataManager.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. //
  2. // KMDataManager.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2024/2/23.
  6. //
  7. import Cocoa
  8. // 数据持久化 【UserDefault、本地存储、数据库】
  9. let kDocumentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
  10. let kAppSupportDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
  11. let kAppSupportOfBundleIdentifierDirectory = kAppSupportDirectory.appendingPathComponent(MainBundle.bundleIdentifier ?? kBundleIdentifier)
  12. class KMDataManager: NSObject {
  13. // 单例
  14. static let `default` = KMDataManager()
  15. var isTabbingWin = false //多页签提示页是否展示中
  16. var toolbarConfigDataUpdated = false
  17. private let launchAppCountKey_ = "kFirstOpenAppCount"
  18. private let launchAppCountForUpdateKey_ = "kLaunchAppCountForUpdate"
  19. private let launchLastVersionKey_ = "kLaunchLastVersion"
  20. private var appFirstLaunch_ = false
  21. var appFirstLaunch: Bool {
  22. get {
  23. return appFirstLaunch_
  24. }
  25. }
  26. private var appFirstLaunchForUpdate_ = false
  27. var appFirstLaunchForUpdate: Bool {
  28. get {
  29. return appFirstLaunchForUpdate_
  30. }
  31. }
  32. // 启动 App 处理数据
  33. func initLaunchData() {
  34. let appLaunchCnt = Self.ud_integer(forKey: launchAppCountKey_) + 1
  35. Self.ud_set(appLaunchCnt, forKey: launchAppCountKey_)
  36. let launchAppCntForUpdate = Self.ud_integer(forKey: launchAppCountForUpdateKey_) + 1
  37. Self.ud_set(launchAppCntForUpdate, forKey: launchAppCountForUpdateKey_)
  38. let appVersion = KMTools.getAppVersion()
  39. if let launchLastVersion = Self.ud_string(forKey: launchLastVersionKey_) {
  40. let result = SKVersionNumber.compareVersionString(launchLastVersion, toVersionString: appVersion)
  41. if result == .orderedAscending {
  42. appFirstLaunchForUpdate_ = true
  43. Self.ud_set(1, forKey: launchAppCountForUpdateKey_)
  44. KMWinBackWindowController.shared.clearRecord()
  45. }
  46. } else {
  47. appFirstLaunch_ = true
  48. }
  49. Self.ud_set(appVersion, forKey: launchLastVersionKey_)
  50. }
  51. }
  52. // MARK: - Paths
  53. extension KMDataManager {
  54. class func fetchAppSupportOfBundleIdentifierDirectory(makeIfNecessary: Bool = true) -> URL {
  55. let url = kAppSupportOfBundleIdentifierDirectory
  56. if makeIfNecessary {
  57. if FileManager.default.fileExists(atPath: url.path) == false {
  58. try?FileManager.default.createDirectory(at: url, withIntermediateDirectories: false)
  59. }
  60. }
  61. return url
  62. }
  63. }
  64. // MARK: - ToolBar
  65. extension KMDataManager {
  66. private static let toolbar_dirname_key_ = "PreferenceData"
  67. private static let toolbar_filename_key_ = "ToolbarConfigData.plist"
  68. private static let toolbar_default_key_ = "default"
  69. private static let toolbar_left_key_ = "left"
  70. private static let toolbar_center_key_ = "center"
  71. private static let toolbar_right_key_ = "right"
  72. // 保存数据 [清空数据时传nil]
  73. class func toolbar_saveData(_ model: KMToolbarConfigModel?) -> Bool {
  74. let dir = self.fetchAppSupportOfBundleIdentifierDirectory().appendingPathComponent(self.toolbar_dirname_key_)
  75. if FileManager.default.fileExists(atPath: dir.path) == false {
  76. try?FileManager.default.createDirectory(at: dir, withIntermediateDirectories: false)
  77. }
  78. let fileUrl = dir.appendingPathComponent(self.toolbar_filename_key_)
  79. if FileManager.default.fileExists(atPath: fileUrl.path) == false {
  80. try?FileManager.default.createFile(atPath: fileUrl.path, contents: nil)
  81. }
  82. if let data = model {
  83. let defaultIdentifiers = [KMLeftControlToolbarItemIdentifier, KMDocumentZoomViewToolbarItemIdentifier,
  84. KMDocumentPreviousPageToolbarItemIdentifier,KMDocumentHomeToolbarItemIdentifier,
  85. KMToolbarFlexibleSpaceItemIdentifier /* 插入可变宽度 */,
  86. KMDocumentAnnotationToolbarItemIdentifier, KMDocumentPageToolbarItemIdentifier, KMDocumentConversonToolbarItemIdentifier,KMDocumentRedactToolbarItemIdentifier,KMDocumentAIToolsToolbarItemIdentifier,KMDocumentViewDisplayToolbarItemIdentifier,KMDocumentScanOCRToolbarItemIdentifier, KMDocumentFormToolbarItemIdentifier, KMDocumentEditToolbarItemIdentifier, KMDocumentDigitalSignToolbarItemIdentifier,
  87. KMDocumentFillSginToolbarItemIdentifier, KMDocumentToolToolbarItemIdentifier,
  88. KMToolbarFlexibleSpaceItemIdentifier /* 插入可变宽度 */,
  89. KMDocumentPrintToolbarItemIdentifier,KMDocumentShareToolbarItemIdentifier,
  90. KMDocumentSearchToolbarItemIdentifier, KMRightControlToolbarItemIdentifier,
  91. KMDocumentPreviousBackToolbarItemIdentifier, KMDocumentFirstLastToolbarItemIdentifier,
  92. KMDocumentPageIndicatorToolbarItemIdentifier, KMDocumentPresentationToolbarItemIdentifier]
  93. var newDict = NSMutableDictionary(dictionary: [self.toolbar_default_key_ : defaultIdentifiers])
  94. let left = model?.leftCellIdentifiers ?? []
  95. newDict.setObject(left, forKey: self.toolbar_left_key_ as NSCopying)
  96. let center = model?.centerCellIdentifiers ?? []
  97. newDict.setObject(center, forKey: self.toolbar_center_key_ as NSCopying)
  98. let right = model?.rightCellIdentifiers ?? []
  99. newDict.setObject(right, forKey: self.toolbar_right_key_ as NSCopying)
  100. if newDict.write(to: fileUrl, atomically: true) {
  101. return true
  102. }
  103. } else { // 清空数据
  104. let newDict = NSMutableDictionary()
  105. if newDict.write(to: fileUrl, atomically: true) {
  106. return true
  107. }
  108. }
  109. return false
  110. }
  111. // 获取数据
  112. class func toolbar_getData() -> KMToolbarConfigModel? {
  113. let dir = self.fetchAppSupportOfBundleIdentifierDirectory().appendingPathComponent(self.toolbar_dirname_key_)
  114. let fileUrl = dir.appendingPathComponent(self.toolbar_filename_key_)
  115. guard let dict = NSDictionary(contentsOfFile: fileUrl.path) else {
  116. return nil
  117. }
  118. if dict.count == 0 {
  119. return nil
  120. }
  121. let model = KMToolbarConfigModel()
  122. model.leftCellIdentifiers = dict[self.toolbar_left_key_] as? [String]
  123. model.centerCellIdentifiers = dict[self.toolbar_center_key_] as? [String]
  124. model.rightCellIdentifiers = dict[self.toolbar_right_key_] as? [String]
  125. return model
  126. }
  127. }
  128. // MARK: - UserDefault
  129. extension KMDataManager {
  130. class func ud_object(forKey defaultName: String) -> Any? {
  131. return self.userD_.object(forKey: defaultName)
  132. }
  133. class func ud_set(_ value: Any?, forKey defaultName: String, sync: Bool = true) {
  134. self.userD_.set(value, forKey: defaultName)
  135. if sync {
  136. self.userD_.synchronize()
  137. }
  138. }
  139. class func ud_removeObject(forKey defaultName: String, sync: Bool = true) {
  140. self.userD_.removeObject(forKey: defaultName)
  141. }
  142. class func ud_string(forKey defaultName: String) -> String? {
  143. return self.userD_.string(forKey: defaultName)
  144. }
  145. class func ud_array(forKey defaultName: String) -> [Any]? {
  146. return self.userD_.array(forKey: defaultName)
  147. }
  148. class func ud_dictionary(forKey defaultName: String) -> [String : Any]? {
  149. return self.userD_.dictionary(forKey: defaultName)
  150. }
  151. class func ud_data(forKey defaultName: String) -> Data? {
  152. return self.userD_.data(forKey: defaultName)
  153. }
  154. class func ud_stringArray(forKey defaultName: String) -> [String]? {
  155. return self.userD_.stringArray(forKey: defaultName)
  156. }
  157. class func ud_integer(forKey defaultName: String) -> Int {
  158. return self.userD_.integer(forKey: defaultName)
  159. }
  160. class func ud_float(forKey defaultName: String) -> Float {
  161. return self.userD_.float(forKey: defaultName)
  162. }
  163. class func ud_double(forKey defaultName: String) -> Double {
  164. return self.userD_.double(forKey: defaultName)
  165. }
  166. class func ud_bool(forKey defaultName: String) -> Bool {
  167. return self.userD_.bool(forKey: defaultName)
  168. }
  169. class func ud_url(forKey defaultName: String) -> URL? {
  170. return self.userD_.url(forKey: defaultName)
  171. }
  172. class func ud_set(_ value: Int, forKey defaultName: String, sync: Bool = true) {
  173. self.userD_.set(value, forKey: defaultName)
  174. if sync {
  175. self.userD_.synchronize()
  176. }
  177. }
  178. class func ud_set(_ value: Float, forKey defaultName: String, sync: Bool = true) {
  179. self.userD_.set(value, forKey: defaultName)
  180. if sync {
  181. self.userD_.synchronize()
  182. }
  183. }
  184. class func ud_set(_ value: Double, forKey defaultName: String, sync: Bool = true) {
  185. self.userD_.set(value, forKey: defaultName)
  186. if sync {
  187. self.userD_.synchronize()
  188. }
  189. }
  190. class func ud_set(_ value: Bool, forKey defaultName: String, sync: Bool = true) {
  191. self.userD_.set(value, forKey: defaultName)
  192. if sync {
  193. self.userD_.synchronize()
  194. }
  195. }
  196. class func ud_set(_ url: URL?, forKey defaultName: String, sync: Bool = true) {
  197. self.userD_.set(url, forKey: defaultName)
  198. if sync {
  199. self.userD_.synchronize()
  200. }
  201. }
  202. // 私有
  203. private class var userD_: UserDefaults {
  204. get {
  205. return UserDefaults.standard
  206. }
  207. }
  208. }
  209. // MARK: - UserDefault 的补充
  210. extension KMDataManager {
  211. private static let userD_dirname_key_ = "KMUserDefaultExtension"
  212. private static let userD_filename_key_ = "KMUserDefaultExtension.plist"
  213. // 保存数据 [清空数据时传nil]
  214. class func udExtension_set(_ value: Any?, forKey defaultName: String) {
  215. // 存储文件路径
  216. let dir = self.fetchAppSupportOfBundleIdentifierDirectory().appendingPathComponent(self.userD_dirname_key_)
  217. if FileManager.default.fileExists(atPath: dir.path) == false {
  218. try?FileManager.default.createDirectory(at: dir, withIntermediateDirectories: false)
  219. }
  220. // 存储文件名称
  221. let fileUrl = dir.appendingPathComponent(self.userD_filename_key_)
  222. if FileManager.default.fileExists(atPath: fileUrl.path) == false {
  223. try?FileManager.default.createFile(atPath: fileUrl.path, contents: nil)
  224. }
  225. // 获取原始文件数据
  226. var info = NSMutableDictionary()
  227. if let data = try?NSDictionary(contentsOf: fileUrl, error: ()) {
  228. info.addEntries(from: data as? [AnyHashable : Any] ?? [:])
  229. }
  230. // 保存数据
  231. info.setObject(value as Any, forKey: defaultName as NSCopying)
  232. info.write(to: fileUrl, atomically: true)
  233. }
  234. // 获取数据
  235. class func udExtension_object(forKey defaultName: String) -> Any? {
  236. // 查找文件
  237. let dir = self.fetchAppSupportOfBundleIdentifierDirectory().appendingPathComponent(self.userD_dirname_key_)
  238. let fileUrl = dir.appendingPathComponent(self.userD_filename_key_)
  239. guard let dict = NSDictionary(contentsOfFile: fileUrl.path) else {
  240. return nil
  241. }
  242. // 获取数据
  243. if dict.count == 0 {
  244. return nil
  245. }
  246. return dict[defaultName]
  247. }
  248. }