diff options
Diffstat (limited to 'Sora/Data/Settings')
| -rw-r--r-- | Sora/Data/Settings/SettingsManager.swift | 128 |
1 files changed, 118 insertions, 10 deletions
diff --git a/Sora/Data/Settings/SettingsManager.swift b/Sora/Data/Settings/SettingsManager.swift index 909016d..b2749e1 100644 --- a/Sora/Data/Settings/SettingsManager.swift +++ b/Sora/Data/Settings/SettingsManager.swift @@ -23,6 +23,11 @@ class SettingsManager: ObservableObject { @AppStorage("preloadedCarouselImages") var preloadedCarouselImages = 3 + @AppStorage("enableICloudSync") + var enableICloudSync: Bool = false + + private var iCloudSyncObservation: NSObjectProtocol? + #if os(macOS) @AppStorage("saveTagsToFile") var saveTagsToFile = false @@ -50,11 +55,32 @@ class SettingsManager: ObservableObject { // MARK: - Computed Properties var bookmarks: [SettingsBookmark] { get { - (Self.decode([SettingsBookmark].self, from: bookmarksData) ?? []) + if enableICloudSync { + if let data = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") { + return (Self.decode([SettingsBookmark].self, from: data) ?? []) + .sorted { $0.date > $1.date } + } + + return (Self.decode([SettingsBookmark].self, from: bookmarksData) ?? []) + .sorted { $0.date > $1.date } + } + + return (Self.decode([SettingsBookmark].self, from: bookmarksData) ?? []) .sorted { $0.date > $1.date } } - set { bookmarksData = Self.encode(newValue) ?? bookmarksData } + set { + let sortedBookmarks = newValue.sorted { $0.date > $1.date } + + bookmarksData = Self.encode(sortedBookmarks) ?? Data() + + if enableICloudSync { + NSUbiquitousKeyValueStore.default.set( + Self.encode(sortedBookmarks), + forKey: "bookmarks" + ) + } + } } var displayRatings: [BooruRating] { @@ -73,11 +99,31 @@ class SettingsManager: ObservableObject { var searchHistory: [BooruSearchQuery] { get { - (Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? []) + if enableICloudSync { + if let data = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") { + return (Self.decode([BooruSearchQuery].self, from: data) ?? []) + .sorted { $0.date > $1.date } + } + + return (Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? []) + .sorted { $0.date > $1.date } + } + + return (Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? []) .sorted { $0.date > $1.date } } - set { searchHistoryData = Self.encode(newValue) ?? searchHistoryData } + set { + let sortedHistory = newValue.sorted { $0.date > $1.date } + + searchHistoryData = Self.encode(sortedHistory) ?? Data() + + if enableICloudSync { + NSUbiquitousKeyValueStore.default.set( + Self.encode(sortedHistory), forKey: "searchHistory" + ) + } + } } var preferredBooru: BooruProvider { @@ -90,14 +136,51 @@ class SettingsManager: ObservableObject { var customProviders: [BooruProviderCustom] { get { - Self.decode( - [BooruProviderCustom].self, - from: customProvidersData - ) ?? [] + if enableICloudSync { + if let data = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") { + return Self.decode([BooruProviderCustom].self, from: data) ?? [] + } + + return Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? [] + } + + return Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? [] } set { - customProvidersData = Self.encode(newValue) ?? customProvidersData + customProvidersData = Self.encode(newValue) ?? Data() + + if enableICloudSync { + NSUbiquitousKeyValueStore.default.set( + Self.encode(newValue), + forKey: "customProviders" + ) + } + } + } + + // MARK: - Initialisation + init() { + iCloudSyncObservation = NotificationCenter.default.addObserver( + forName: NSUbiquitousKeyValueStore.didChangeExternallyNotification, + object: NSUbiquitousKeyValueStore.default, + queue: .main + ) { [weak self] _ in + guard let localSelf = self, localSelf.enableICloudSync else { return } // swiftlint:disable:this self_binding + + if let data = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") { + localSelf.bookmarksData = data + } + + if let data = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") { + localSelf.searchHistoryData = data + } + + if let data = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") { + localSelf.customProvidersData = data + } + + localSelf.objectWillChange.send() } } @@ -132,9 +215,27 @@ class SettingsManager: ObservableObject { #endif } + func syncToICloud() { + if enableICloudSync { + NSUbiquitousKeyValueStore.default.set(bookmarksData, forKey: "bookmarks") + NSUbiquitousKeyValueStore.default.set(searchHistoryData, forKey: "searchHistory") + NSUbiquitousKeyValueStore.default.set(customProvidersData, forKey: "customProviders") + } + } + // MARK: - Bookmark Management func addBookmark(provider: BooruProvider, tags: [String]) { - bookmarks.append(SettingsBookmark(provider: provider, tags: tags.map { $0.lowercased() })) + var updatedBookmarks = bookmarks + + updatedBookmarks.append( + SettingsBookmark(provider: provider, tags: tags.map { $0.lowercased() }) + ) + + if let data = Self.encode(updatedBookmarks), data.count < 1_000_000 { // 1 MB + bookmarks = updatedBookmarks + } else { + debugPrint("SettingsManager.addBookmark: iCloud data limit exceeded") + } } func removeBookmark(at offsets: IndexSet) { @@ -200,4 +301,11 @@ class SettingsManager: ObservableObject { } } #endif + + // MARK: - Deinitialisation + deinit { + if let observation = iCloudSyncObservation { + NotificationCenter.default.removeObserver(observation) + } + } } |