1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
// SPDX-License-Identifier: GPL-2.0-or-later
import FileProvider
import Foundation
import NextcloudFileProviderKit
import os
///
/// Abstraction for the user defaults specific to file provider domains.
///
struct FileProviderDomainDefaults {
///
/// > Warning: Do not change the raw values of these keys, as they are used in UserDefaults. Any change would make the already stored value inaccessible and be like a reset.
///
private enum ConfigKey: String {
case trashDeletionEnabled
case user
case userId
case serverUrl
}
///
/// The file provider domain identifier which the current settings belong to.
///
let identifier: NSFileProviderDomainIdentifier
let logger: FileProviderLogger
init(identifier: NSFileProviderDomainIdentifier, log: any FileProviderLogging) {
self.identifier = identifier
self.logger = FileProviderLogger(category: "FileProviderDomainDefaults", log: log)
}
///
/// Either fetch the existing settings for the given domain identifier or create a new empty dictionary.
///
private var internalConfig: [String: Any] {
get {
let defaults = UserDefaults.standard
if let settings = defaults.dictionary(forKey: identifier.rawValue) {
return settings
}
let dictionary: [String: Any] = [:]
defaults.setValue(dictionary, forKey: identifier.rawValue)
return dictionary
}
set {
UserDefaults.standard.setValue(newValue, forKey: identifier.rawValue)
}
}
///
/// The address of the server to connect to.
///
var serverUrl: String? {
get {
let identifier = self.identifier.rawValue
if let value = internalConfig[ConfigKey.serverUrl.rawValue] as? String {
logger.debug("Returning existing value \"\(value)\" for \"serverUrl\" for file provider domain \"\(identifier)\".")
return value
} else {
logger.debug("No existing value for \"serverUrl\" for file provider domain \"\(identifier)\" found.")
return nil
}
}
set {
let identifier = self.identifier.rawValue
if newValue == nil {
logger.debug("Removing key \"serverUrl\" for file provider domain \"\(identifier)\" because the new value is nil.")
internalConfig.removeValue(forKey: ConfigKey.serverUrl.rawValue)
} else if newValue == "" {
logger.error("Ignoring new value for \"serverUrl\" because it is an empty string for file provider domain \"\(identifier)\"!")
} else {
internalConfig[ConfigKey.serverUrl.rawValue] = newValue
}
}
}
///
/// Whether trash deletion is enabled or not.
///
var trashDeletionEnabled: Bool {
get {
let identifier = self.identifier.rawValue
if let value = internalConfig[ConfigKey.trashDeletionEnabled.rawValue] as? Bool {
logger.debug("Returning existing value \"\(value)\" for \"trashDeletionEnabled\" for file provider domain \"\(identifier)\".")
return value
} else {
return false
}
}
set {
let identifier = self.identifier.rawValue
logger.error("Setting value \"\(newValue)\" for \"trashDeletionEnabled\" for file provider domain \"\(identifier)\".")
internalConfig[ConfigKey.trashDeletionEnabled.rawValue] = newValue
}
}
///
/// The user name associated with the domain.
///
var user: String? {
get {
let identifier = self.identifier.rawValue
if let value = internalConfig[ConfigKey.user.rawValue] as? String {
logger.debug("Returning existing value \"\(value)\" for \"user\" for file provider domain \"\(identifier)\".")
return value
} else {
logger.debug("No existing value for \"user\" for file provider domain \"\(identifier)\" found.")
return nil
}
}
set {
let identifier = self.identifier.rawValue
if newValue == nil {
logger.debug("Removing key \"user\" for file provider domain \"\(identifier)\" because the new value is nil.")
internalConfig.removeValue(forKey: ConfigKey.user.rawValue)
} else if newValue == "" {
logger.error("Ignoring new value for \"user\" because it is an empty string for file provider domain \"\(identifier)\"!")
} else {
internalConfig[ConfigKey.user.rawValue] = newValue
}
}
}
///
/// The full user identifier associated with the domain.
///
var userId: String? {
get {
let identifier = self.identifier.rawValue
if let value = internalConfig[ConfigKey.userId.rawValue] as? String {
logger.debug("Returning existing value \"\(value)\" for \"userId\" for file provider domain \"\(identifier)\".")
return value
} else {
logger.debug("No existing value for \"userId\" for file provider domain \"\(identifier)\" found.")
return nil
}
}
set {
let identifier = self.identifier.rawValue
if newValue == nil {
logger.debug("Removing key \"userId\" for file provider domain \"\(identifier)\" because the new value is nil.")
internalConfig.removeValue(forKey: ConfigKey.userId.rawValue)
} else if newValue == "" {
logger.error("Ignoring new value for \"userId\" because it is an empty string for file provider domain \"\(identifier)\"!")
} else {
internalConfig[ConfigKey.userId.rawValue] = newValue
}
}
}
///
/// Whether a value for `trashDeletionEnabled` has been explicitly set.
///
lazy var trashDeletionSet = internalConfig[ConfigKey.trashDeletionEnabled.rawValue] != nil
}
|