mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 00:08:39 +09:00
137 lines
5 KiB
Swift
137 lines
5 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import Foundation
|
|
import Shared
|
|
|
|
open class NSUserDefaultsPrefs: Prefs {
|
|
|
|
fileprivate let prefixWithDot: String
|
|
fileprivate let userDefaults: UserDefaults
|
|
|
|
open func getBranchPrefix() -> String {
|
|
return self.prefixWithDot
|
|
}
|
|
|
|
init(prefix: String, userDefaults: UserDefaults) {
|
|
self.prefixWithDot = prefix + (prefix.endsWith(".") ? "" : ".")
|
|
self.userDefaults = userDefaults
|
|
}
|
|
|
|
init(prefix: String) {
|
|
self.prefixWithDot = prefix + (prefix.endsWith(".") ? "" : ".")
|
|
self.userDefaults = UserDefaults(suiteName: AppInfo.sharedContainerIdentifier)!
|
|
}
|
|
|
|
open func branch(_ branch: String) -> Prefs {
|
|
let prefix = self.prefixWithDot + branch + "."
|
|
return NSUserDefaultsPrefs(prefix: prefix, userDefaults: self.userDefaults)
|
|
}
|
|
|
|
// Preferences are qualified by the profile's local name.
|
|
// Connecting a profile to a Firefox Account, or changing to another, won't alter this.
|
|
fileprivate func qualifyKey(_ key: String) -> String {
|
|
return self.prefixWithDot + key
|
|
}
|
|
|
|
open func setInt(_ value: Int32, forKey defaultName: String) {
|
|
// Why aren't you using userDefaults.setInteger?
|
|
// Because userDefaults.getInteger returns a non-optional; it's impossible
|
|
// to tell whether there's a value set, and you thus can't distinguish
|
|
// between "not present" and zero.
|
|
// Yeah, NSUserDefaults is meant to be used for storing "defaults", not data.
|
|
setObject(NSNumber(value: value), forKey: defaultName)
|
|
}
|
|
|
|
open func setTimestamp(_ value: Timestamp, forKey defaultName: String) {
|
|
setLong(value, forKey: defaultName)
|
|
}
|
|
|
|
open func setLong(_ value: UInt64, forKey defaultName: String) {
|
|
setObject(NSNumber(value: value), forKey: defaultName)
|
|
}
|
|
|
|
open func setLong(_ value: Int64, forKey defaultName: String) {
|
|
setObject(NSNumber(value: value), forKey: defaultName)
|
|
}
|
|
|
|
open func setString(_ value: String, forKey defaultName: String) {
|
|
setObject(value as AnyObject?, forKey: defaultName)
|
|
}
|
|
|
|
open func setObject(_ value: Any?, forKey defaultName: String) {
|
|
userDefaults.set(value, forKey: qualifyKey(defaultName))
|
|
}
|
|
|
|
open func stringForKey(_ defaultName: String) -> String? {
|
|
// stringForKey converts numbers to strings, which is almost always a bug.
|
|
return userDefaults.object(forKey: qualifyKey(defaultName)) as? String
|
|
}
|
|
|
|
open func setBool(_ value: Bool, forKey defaultName: String) {
|
|
setObject(NSNumber(value: value as Bool), forKey: defaultName)
|
|
}
|
|
|
|
open func boolForKey(_ defaultName: String) -> Bool? {
|
|
// boolForKey just returns false if the key doesn't exist. We need to
|
|
// distinguish between false and non-existent keys, so use objectForKey
|
|
// and cast the result instead.
|
|
let number = userDefaults.object(forKey: qualifyKey(defaultName)) as? NSNumber
|
|
return number?.boolValue
|
|
}
|
|
|
|
fileprivate func nsNumberForKey(_ defaultName: String) -> NSNumber? {
|
|
return userDefaults.object(forKey: qualifyKey(defaultName)) as? NSNumber
|
|
}
|
|
|
|
open func unsignedLongForKey(_ defaultName: String) -> UInt64? {
|
|
return nsNumberForKey(defaultName)?.uint64Value
|
|
}
|
|
|
|
open func timestampForKey(_ defaultName: String) -> Timestamp? {
|
|
return unsignedLongForKey(defaultName)
|
|
}
|
|
|
|
open func longForKey(_ defaultName: String) -> Int64? {
|
|
return nsNumberForKey(defaultName)?.int64Value
|
|
}
|
|
|
|
open func objectForKey<T: Any>(_ defaultName: String) -> T? {
|
|
return userDefaults.object(forKey: qualifyKey(defaultName)) as? T
|
|
}
|
|
|
|
open func intForKey(_ defaultName: String) -> Int32? {
|
|
return nsNumberForKey(defaultName)?.int32Value
|
|
}
|
|
|
|
open func stringArrayForKey(_ defaultName: String) -> [String]? {
|
|
let objects = userDefaults.stringArray(forKey: qualifyKey(defaultName))
|
|
if let strings = objects {
|
|
return strings
|
|
}
|
|
return nil
|
|
}
|
|
|
|
open func arrayForKey(_ defaultName: String) -> [Any]? {
|
|
return userDefaults.array(forKey: qualifyKey(defaultName)) as [Any]?
|
|
}
|
|
|
|
open func dictionaryForKey(_ defaultName: String) -> [String: Any]? {
|
|
return userDefaults.dictionary(forKey: qualifyKey(defaultName)) as [String: Any]?
|
|
}
|
|
|
|
open func removeObjectForKey(_ defaultName: String) {
|
|
userDefaults.removeObject(forKey: qualifyKey(defaultName))
|
|
}
|
|
|
|
open func clearAll() {
|
|
// TODO: userDefaults.removePersistentDomainForName() has no effect for app group suites.
|
|
// iOS Bug? Iterate and remove each manually for now.
|
|
for key in userDefaults.dictionaryRepresentation().keys {
|
|
if key.startsWith(prefixWithDot) {
|
|
userDefaults.removeObject(forKey: key)
|
|
}
|
|
}
|
|
}
|
|
}
|