Skip to content

Commit dd3a9fa

Browse files
committed
Add persistent domains code.
1 parent 18fb5f5 commit dd3a9fa

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
lines changed

Foundation/UserDefaults.swift

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,18 @@ open class UserDefaults: NSObject {
404404
CFPreferencesRemoveSuitePreferencesFromApp(kCFPreferencesCurrentApplication, suiteName._cfObject)
405405
}
406406

407-
open func dictionaryRepresentation() -> [String : Any] {
407+
open func dictionaryRepresentation() -> [String: Any] {
408+
return _dictionaryRepresentation(searchingOutsideOfSuite: true)
409+
}
410+
411+
private func _dictionaryRepresentation(searchingOutsideOfSuite: Bool) -> [String: Any] {
412+
let registeredDefaultsIfAllowed = searchingOutsideOfSuite ? registeredDefaults : [:]
413+
408414
guard let aPref = CFPreferencesCopyMultiple(nil, kCFPreferencesCurrentApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost),
409415
let bPref = (aPref._swiftObject) as? [NSString: Any] else {
410-
return registeredDefaults
416+
return registeredDefaultsIfAllowed
411417
}
412-
var allDefaults = registeredDefaults
418+
var allDefaults = registeredDefaultsIfAllowed
413419

414420
for (key, value) in bPref {
415421
if let value = plistValueAsNSObject(value) {
@@ -457,9 +463,33 @@ open class UserDefaults: NSObject {
457463
_volatileDomainsLock.unlock()
458464
}
459465

460-
open func persistentDomain(forName domainName: String) -> [String : Any]? { NSUnimplemented() }
461-
open func setPersistentDomain(_ domain: [String : Any], forName domainName: String) { NSUnimplemented() }
462-
open func removePersistentDomain(forName domainName: String) { NSUnimplemented() }
466+
open func persistentDomain(forName domainName: String) -> [String : Any]? {
467+
return UserDefaults(suiteName: domainName)?._dictionaryRepresentation(searchingOutsideOfSuite: false)
468+
}
469+
470+
open func setPersistentDomain(_ domain: [String : Any], forName domainName: String) {
471+
if let defaults = UserDefaults(suiteName: domainName) {
472+
for key in defaults._dictionaryRepresentation(searchingOutsideOfSuite: false).keys {
473+
defaults.removeObject(forKey: key)
474+
}
475+
476+
for (key, value) in domain {
477+
defaults.set(value, forKey: key)
478+
}
479+
}
480+
481+
NotificationCenter.default.post(name: UserDefaults.didChangeNotification, object: self)
482+
}
483+
484+
open func removePersistentDomain(forName domainName: String) {
485+
if let defaults = UserDefaults(suiteName: domainName) {
486+
for key in defaults._dictionaryRepresentation(searchingOutsideOfSuite: false).keys {
487+
defaults.removeObject(forKey: key)
488+
}
489+
490+
NotificationCenter.default.post(name: UserDefaults.didChangeNotification, object: self)
491+
}
492+
}
463493

464494
open func synchronize() -> Bool {
465495
return CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication)

TestFoundation/TestUserDefaults.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class TestUserDefaults : XCTestCase {
3939
("test_setValue_IntFromString", test_setValue_IntFromString ),
4040
("test_setValue_DoubleFromString", test_setValue_DoubleFromString ),
4141
("test_volatileDomains", test_volatileDomains),
42+
("test_persistentDomain", test_persistentDomain ),
4243
]
4344
}
4445

@@ -289,4 +290,43 @@ class TestUserDefaults : XCTestCase {
289290
XCTAssertEqual(defaultsIn[dataKey] as! Data, defaultsOut[dataKey] as! Data)
290291
XCTAssertEqual(defaultsIn[boolKey] as! Bool, defaultsOut[boolKey] as! Bool)
291292
}
293+
294+
func test_persistentDomain() {
295+
let int = (key: "An Integer", value: 1234)
296+
let double = (key: "A Double", value: 5678.0)
297+
let string = (key: "A String", value: "Some string")
298+
let array = (key: "An Array", value: [ 1, 2, 3, 4, "Surprise" ] as [AnyHashable])
299+
let dictionary = (key: "A Dictionary", value: [ "Swift": "Imperative", "Haskell": "Functional", "LISP": "LISP", "Today": Date() ] as [String: AnyHashable])
300+
301+
let domainName = "org.swift.Foundation.TestPersistentDomainName"
302+
303+
let defaults1 = UserDefaults(suiteName: nil)!
304+
305+
defaults1.removePersistentDomain(forName: domainName)
306+
XCTAssertNil(defaults1.persistentDomain(forName: domainName))
307+
308+
defaults1.setPersistentDomain([int.key: int.value,
309+
double.key: double.value,
310+
string.key: string.value,
311+
array.key: array.value,
312+
dictionary.key: dictionary.value],
313+
forName: domainName)
314+
315+
let defaults2 = UserDefaults(suiteName: nil)!
316+
let returned = defaults2.persistentDomain(forName: domainName)
317+
XCTAssertNotNil(returned)
318+
319+
if let returned = returned {
320+
XCTAssertEqual(returned[int.key] as! Int, int.value)
321+
XCTAssertEqual(returned[double.key] as! Double, double.value)
322+
XCTAssertEqual(returned[string.key] as! String, string.value)
323+
XCTAssertEqual(returned[array.key] as! [AnyHashable], array.value)
324+
XCTAssertEqual(returned[dictionary.key] as! [String: AnyHashable], dictionary.value)
325+
}
326+
327+
defaults2.removeSuite(named: domainName)
328+
329+
let defaults3 = UserDefaults(suiteName: nil)!
330+
XCTAssertNil(defaults3.persistentDomain(forName: domainName))
331+
}
292332
}

0 commit comments

Comments
 (0)