Reputation: 1233
I a developing a macOS commandline application in Xcode, which uses User Defaults. I have the following code for my User Defaults
if let configDefaults = UserDefaults.init(suiteName: "com.tests.configuration") {
configDefaults.set("myStringValue", forKey: "stringKey")
configDefaults.synchronize()
print(configDefaults.dictionaryRepresentation())
}
This will create my own .plist
file in the ~/Library/Preferences
folder. If I look into the file, I can see only my single value which I added, which is perfectly fine. But when I call dictionaryRepresentation()
on my UserDefaults object, the there are a lot of other attributes (I guess from the shared UserDefaults object), like
com.apple.trackpad.twoFingerFromRightEdgeSwipeGesture
or AKLastEmailListRequestDateKey
Looking into the documentation of UserDefaults, it seems that this has to do with the search list of UserDefaults and that the standard
object is in the search list:
func dictionaryRepresentation() -> [String : Any]
Returns a dictionary that contains a union of all key-value pairs in the domains in the search list.
There are also the methods addSuite
and removeSuite
for a UserDefaults object, so I am guessing I need to remove the .standard
suite from my configDefaults
object, but I don't know the name, which should be used for that in the method.
Is it possible to remove the .standard
defaults from the dictionary representation? I basically just want all of my own data in a dictionary, nothing more.
The reason I am trying to get only my values from the UserDefaults, is that a have a number of object of a custom type Connection
(which store the configuration to connect to a server), which are saved in the UserDefaults. On program start I want to be able to load all objects into my app. Therefore I thought I could use dictionaryRepresentation()
, as it would return all elements in the UserDefaults. But then there should be only my Connection
objects in the dictionary, so that I can cast it to [String: Connection]
.
Upvotes: 1
Views: 573
Reputation: 1233
Though the other solution proposed by Ken Thomases may be better from a design standpoint, I've found a solution that does exactly what I initially wanted. Calling
UserDefaults.standard.persistentDomain(forName: "com.company.TestApp.configuration")
Returns a dictionary containing only the values I've added to the domain com.company.TestApp.configuration
, using
let configs = UserDefaults.init(suiteName: "com.company.TestApp.configuration")!
configs.set(someData, forKey: someKey)
Strangely in the Apple documentation says this about persistentDomain(forName:)
:
Calling this method is equivalent to initializing a user defaults object with
init(suiteName:)
passing domainName and calling thedictionaryRepresentation()
method on it.
But this is not the case (see my question). Clarification on that subject is more than welcome.
Upvotes: 1
Reputation: 90641
Given your purpose (in your latest edit of your question), what you should do is store a collection of Connection
objects under a single key. Then, look up that key to get the collection.
It's not clear if the collection should be an array of Connection
objects or a dictionary mapping strings to Connection
s. That's a choice you can make.
But, in any case, you shouldn't rely on the defaults being empty of everything else.
In other words, you would do:
UserDefaults.standard.set(yourStringToConnectionDictionary, forKey:"yourSingleKey")
and later:
let connectionMap = UserDefaults.dictionary(forKey:"yourSingleKey")
then look up Connection
s in the connectionMap
by their name/ID/whatever.
Upvotes: 2