9
9
10
10
import CoreFoundation
11
11
12
- private var registeredDefaults = [ String: Any ] ( )
12
+ private var registeredDefaults = [ String: NSObject ] ( )
13
13
private var sharedDefaults = UserDefaults ( )
14
14
15
+ internal func plistValueAsNSObject( _ value: Any ) -> NSObject ? {
16
+ let nsValue : NSObject
17
+
18
+ // Converts a value to the internal representation. Internalized values are
19
+ // stored as NSObject derived objects in the registration dictionary.
20
+ if let val = value as? String {
21
+ nsValue = val. _nsObject
22
+ } else if let val = value as? URL {
23
+ nsValue = val. path. _nsObject
24
+ } else if let val = value as? Int {
25
+ nsValue = NSNumber ( value: val)
26
+ } else if let val = value as? Double {
27
+ nsValue = NSNumber ( value: val)
28
+ } else if let val = value as? Bool {
29
+ nsValue = NSNumber ( value: val)
30
+ } else if let val = value as? Data {
31
+ nsValue = val. _nsObject
32
+ } else if let val = value as? NSObject {
33
+ nsValue = val
34
+ } else {
35
+ return nil
36
+ }
37
+
38
+ return nsValue
39
+ }
40
+
41
+ private extension Dictionary {
42
+ func convertingValuesToNSObjects( ) -> [ Key : NSObject ] ? {
43
+ var result : [ Key : NSObject ] = [ : ]
44
+
45
+ for (key, value) in self {
46
+ if let nsValue = plistValueAsNSObject ( value) {
47
+ result [ key] = nsValue
48
+ } else {
49
+ return nil
50
+ }
51
+ }
52
+
53
+ return result
54
+ }
55
+ }
56
+
57
+ private extension Dictionary where Value == NSObject {
58
+ mutating func merge( convertingValuesToNSObject source: [ Key : Any ] , uniquingKeysWith block: ( NSObject , NSObject ) throws -> Value ) rethrows -> Bool {
59
+ if let converted = source. convertingValuesToNSObjects ( ) {
60
+ try self . merge ( converted, uniquingKeysWith: block)
61
+ return true
62
+ } else {
63
+ return false
64
+ }
65
+ }
66
+ }
67
+
15
68
open class UserDefaults : NSObject {
16
69
private let suite : String ?
17
70
@@ -31,9 +84,17 @@ open class UserDefaults: NSObject {
31
84
/// nil suite means use the default search list that +standardUserDefaults uses
32
85
public init ? ( suiteName suitename: String ? ) {
33
86
suite = suitename
87
+ super. init ( )
88
+
89
+ setVolatileDomain ( UserDefaults . _parsedArgumentsDomain, forName: UserDefaults . argumentDomain)
34
90
}
35
91
36
92
open func object( forKey defaultName: String ) -> Any ? {
93
+ let argumentDomain = volatileDomain ( forName: UserDefaults . argumentDomain)
94
+ if let object = argumentDomain [ defaultName] {
95
+ return object
96
+ }
97
+
37
98
func getFromRegistered( ) -> Any ? {
38
99
return registeredDefaults [ defaultName]
39
100
}
@@ -265,30 +326,8 @@ open class UserDefaults: NSObject {
265
326
}
266
327
267
328
open func register( defaults registrationDictionary: [ String : Any ] ) {
268
- for (key, value) in registrationDictionary {
269
- let nsValue : NSObject
270
-
271
- // Converts a value to the internal representation. Internalized values are
272
- // stored as NSObject derived objects in the registration dictionary.
273
- if let val = value as? String {
274
- nsValue = val. _nsObject
275
- } else if let val = value as? URL {
276
- nsValue = val. path. _nsObject
277
- } else if let val = value as? Int {
278
- nsValue = NSNumber ( value: val)
279
- } else if let val = value as? Double {
280
- nsValue = NSNumber ( value: val)
281
- } else if let val = value as? Bool {
282
- nsValue = NSNumber ( value: val)
283
- } else if let val = value as? Data {
284
- nsValue = val. _nsObject
285
- } else if let val = value as? NSObject {
286
- nsValue = val
287
- } else {
288
- fatalError ( " The type of 'value' passed to UserDefaults.register(defaults:) is not supported. " )
289
- }
290
-
291
- registeredDefaults [ key] = nsValue
329
+ if !registeredDefaults. merge ( convertingValuesToNSObject: registrationDictionary, uniquingKeysWith: { $1 } ) {
330
+ fatalError ( " The type of 'value' passed to UserDefaults.register(defaults:) is not supported. " )
292
331
}
293
332
}
294
333
@@ -307,16 +346,50 @@ open class UserDefaults: NSObject {
307
346
var allDefaults = registeredDefaults
308
347
309
348
for (key, value) in bPref {
310
- allDefaults [ key. _swiftObject] = value
349
+ if let value = plistValueAsNSObject ( value) {
350
+ allDefaults [ key. _swiftObject] = value
351
+ }
311
352
}
312
353
313
354
return allDefaults
314
355
}
315
356
316
- open var volatileDomainNames : [ String ] { NSUnimplemented ( ) }
317
- open func volatileDomain( forName domainName: String ) -> [ String : Any ] { NSUnimplemented ( ) }
318
- open func setVolatileDomain( _ domain: [ String : Any ] , forName domainName: String ) { NSUnimplemented ( ) }
319
- open func removeVolatileDomain( forName domainName: String ) { NSUnimplemented ( ) }
357
+ private static let _parsedArgumentsDomain : [ String : Any ] = UserDefaults . _parseArguments ( ProcessInfo . processInfo. arguments)
358
+
359
+ private var _volatileDomains : [ String : [ String : NSObject ] ] = [ : ]
360
+ private let _volatileDomainsLock = NSLock ( )
361
+
362
+ open var volatileDomainNames : [ String ] {
363
+ _volatileDomainsLock. lock ( )
364
+ let names = Array ( _volatileDomains. keys)
365
+ _volatileDomainsLock. unlock ( )
366
+
367
+ return names
368
+ }
369
+
370
+ open func volatileDomain( forName domainName: String ) -> [ String : Any ] {
371
+ _volatileDomainsLock. lock ( )
372
+ let domain = _volatileDomains [ domainName]
373
+ _volatileDomainsLock. unlock ( )
374
+
375
+ return domain ?? [ : ]
376
+ }
377
+
378
+ open func setVolatileDomain( _ domain: [ String : Any ] , forName domainName: String ) {
379
+ _volatileDomainsLock. lock ( )
380
+ var convertedDomain : [ String : NSObject ] = _volatileDomains [ domainName] ?? [ : ]
381
+ if !convertedDomain. merge ( convertingValuesToNSObject: domain, uniquingKeysWith: { $1 } ) {
382
+ fatalError ( " The type of 'value' passed to UserDefaults.setVolatileDomain(_:forName:) is not supported. " )
383
+ }
384
+ _volatileDomains [ domainName] = convertedDomain
385
+ _volatileDomainsLock. unlock ( )
386
+ }
387
+
388
+ open func removeVolatileDomain( forName domainName: String ) {
389
+ _volatileDomainsLock. lock ( )
390
+ _volatileDomains. removeValue ( forKey: domainName)
391
+ _volatileDomainsLock. unlock ( )
392
+ }
320
393
321
394
open func persistentDomain( forName domainName: String ) -> [ String : Any ] ? { NSUnimplemented ( ) }
322
395
open func setPersistentDomain( _ domain: [ String : Any ] , forName domainName: String ) { NSUnimplemented ( ) }
0 commit comments