I added a Settings bundle to my app and in Xcode it appears in the root of my project tree view.
The Root.plist
file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>Service</string>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Hostname</string>
<key>Key</key>
<string>service_hostname</string>
<!-- and so on -->
When I open the Settings app on iOS the entry appears at the bottom and I can display and edit my settings perfectly fine.
However I cannot retrieve these values from code. Here's my code:
static func loadSettings() {
let ud = NSUserDefaults.standardUserDefaults()
ud.synchronize()
Settings.hostName = ud.stringForKey("service_hostname")
// etc
}
I also tried ud.objectForKey
and ud.valueForKey
- both return nil
as well.
After setting Settings.hostName
the Xcode debugger reports it has a value of nil
despite me setting an explicit value in the Settings app.
I saw this thread ( iPhone App : How to get default value from root.plist? ) where someone posted a chunk of Objective-C code that manually loads the Root.plist
file directly into an NSMutableDictionary
and calls NSUserDefaults.standardUserDefaults().registerDefaults
but that seems like a hack (and I can't get it to work in Swift because the compiler says that stringByAppendingPathComponent
doesn't exist anymore)
Why isn't NSUserDefaults
picking up the settings from the Settings app?
You should register your defaults so that it will sync up. source from here
Keep in mind that you should also use registerDefaults: when your app uses a Settings Bundle. Since you already specified default values inside the settings bundle’s plist, you may expect that your app picks these up automatically. However, that is not the case. The information contained in the settings bundle is only read by the iOS Settings.app and never by your app. In order to have your app use the same defaults as shown inside the Settings.app, you have to manually copy the user defaults keys and their default values into a separate plist file and register it with the defaults database as shown above.
Apparently the cause is that if my settings in the
plist
have defaults defined and the user has not explicitly set a value, then the value displayed in the Settings app will be the defaults from theplist
file, however theNSUserDefaults
API will still returnnil
.Unfortunately this means that if the default value is meaningful (such as a default web-service address URI: "
http://www.example.com
") it must exist twice in my project: as a default in theplist
and in my program code:Root.plist:
Program.swift:
That's surprising.
Default values can be taken from
Settings.bundle
and added to UserDefaults. Following function can be called inAppDelegate.swift
fromdidFinishLaunchingWithOptions
.