Add persistent domains code.
diff --git a/Foundation/UserDefaults.swift b/Foundation/UserDefaults.swift
index 7d85603..dfcd89c 100644
--- a/Foundation/UserDefaults.swift
+++ b/Foundation/UserDefaults.swift
@@ -404,12 +404,18 @@
CFPreferencesRemoveSuitePreferencesFromApp(kCFPreferencesCurrentApplication, suiteName._cfObject)
}
- open func dictionaryRepresentation() -> [String : Any] {
+ open func dictionaryRepresentation() -> [String: Any] {
+ return _dictionaryRepresentation(searchingOutsideOfSuite: true)
+ }
+
+ private func _dictionaryRepresentation(searchingOutsideOfSuite: Bool) -> [String: Any] {
+ let registeredDefaultsIfAllowed = searchingOutsideOfSuite ? registeredDefaults : [:]
+
guard let aPref = CFPreferencesCopyMultiple(nil, kCFPreferencesCurrentApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost),
let bPref = (aPref._swiftObject) as? [NSString: Any] else {
- return registeredDefaults
+ return registeredDefaultsIfAllowed
}
- var allDefaults = registeredDefaults
+ var allDefaults = registeredDefaultsIfAllowed
for (key, value) in bPref {
if let value = plistValueAsNSObject(value) {
@@ -457,9 +463,33 @@
_volatileDomainsLock.unlock()
}
- open func persistentDomain(forName domainName: String) -> [String : Any]? { NSUnimplemented() }
- open func setPersistentDomain(_ domain: [String : Any], forName domainName: String) { NSUnimplemented() }
- open func removePersistentDomain(forName domainName: String) { NSUnimplemented() }
+ open func persistentDomain(forName domainName: String) -> [String : Any]? {
+ return UserDefaults(suiteName: domainName)?._dictionaryRepresentation(searchingOutsideOfSuite: false)
+ }
+
+ open func setPersistentDomain(_ domain: [String : Any], forName domainName: String) {
+ if let defaults = UserDefaults(suiteName: domainName) {
+ for key in defaults._dictionaryRepresentation(searchingOutsideOfSuite: false).keys {
+ defaults.removeObject(forKey: key)
+ }
+
+ for (key, value) in domain {
+ defaults.set(value, forKey: key)
+ }
+ }
+
+ NotificationCenter.default.post(name: UserDefaults.didChangeNotification, object: self)
+ }
+
+ open func removePersistentDomain(forName domainName: String) {
+ if let defaults = UserDefaults(suiteName: domainName) {
+ for key in defaults._dictionaryRepresentation(searchingOutsideOfSuite: false).keys {
+ defaults.removeObject(forKey: key)
+ }
+
+ NotificationCenter.default.post(name: UserDefaults.didChangeNotification, object: self)
+ }
+ }
open func synchronize() -> Bool {
return CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication)
diff --git a/TestFoundation/TestUserDefaults.swift b/TestFoundation/TestUserDefaults.swift
index c5d0f5b..4ad257f 100644
--- a/TestFoundation/TestUserDefaults.swift
+++ b/TestFoundation/TestUserDefaults.swift
@@ -39,6 +39,7 @@
("test_setValue_IntFromString", test_setValue_IntFromString ),
("test_setValue_DoubleFromString", test_setValue_DoubleFromString ),
("test_volatileDomains", test_volatileDomains),
+ ("test_persistentDomain", test_persistentDomain ),
]
}
@@ -289,4 +290,43 @@
XCTAssertEqual(defaultsIn[dataKey] as! Data, defaultsOut[dataKey] as! Data)
XCTAssertEqual(defaultsIn[boolKey] as! Bool, defaultsOut[boolKey] as! Bool)
}
+
+ func test_persistentDomain() {
+ let int = (key: "An Integer", value: 1234)
+ let double = (key: "A Double", value: 5678.0)
+ let string = (key: "A String", value: "Some string")
+ let array = (key: "An Array", value: [ 1, 2, 3, 4, "Surprise" ] as [AnyHashable])
+ let dictionary = (key: "A Dictionary", value: [ "Swift": "Imperative", "Haskell": "Functional", "LISP": "LISP", "Today": Date() ] as [String: AnyHashable])
+
+ let domainName = "org.swift.Foundation.TestPersistentDomainName"
+
+ let defaults1 = UserDefaults(suiteName: nil)!
+
+ defaults1.removePersistentDomain(forName: domainName)
+ XCTAssertNil(defaults1.persistentDomain(forName: domainName))
+
+ defaults1.setPersistentDomain([int.key: int.value,
+ double.key: double.value,
+ string.key: string.value,
+ array.key: array.value,
+ dictionary.key: dictionary.value],
+ forName: domainName)
+
+ let defaults2 = UserDefaults(suiteName: nil)!
+ let returned = defaults2.persistentDomain(forName: domainName)
+ XCTAssertNotNil(returned)
+
+ if let returned = returned {
+ XCTAssertEqual(returned[int.key] as! Int, int.value)
+ XCTAssertEqual(returned[double.key] as! Double, double.value)
+ XCTAssertEqual(returned[string.key] as! String, string.value)
+ XCTAssertEqual(returned[array.key] as! [AnyHashable], array.value)
+ XCTAssertEqual(returned[dictionary.key] as! [String: AnyHashable], dictionary.value)
+ }
+
+ defaults2.removeSuite(named: domainName)
+
+ let defaults3 = UserDefaults(suiteName: nil)!
+ XCTAssertNil(defaults3.persistentDomain(forName: domainName))
+ }
}