Parameter Set Parameters Returning Zero

I added a set of settings to my application, and in Xcode it appeared at the root of my view of the project tree.

The Root.plist file is as follows:

 <?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 in iOS, the entry appears below, and I can perfectly display and edit my settings.

However, I cannot get these values ​​from the code. Here is 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 returned nil .

After setting Settings.hostName the Xcode debugger reports show that it is nil , despite the fact that I set an explicit value in the Settings application.

I saw this topic ( iPhone App: how to get the default value from root.plist? ), Where someone posted a piece of Objective-C code that manually loads Root.plist directly into NSMutableDictionary and calls NSUserDefaults.standardUserDefaults().registerDefaults , but it looks like a hack (and I can't get it to work in Swift because the compiler says that stringByAppendingPathComponent no longer exists)

Why doesn't NSUserDefaults select settings from the Settings app?

+5
source share
3 answers

Apparently, the reason is that if my settings in plist defined by default and the user has not explicitly set a value, then the value displayed in the Settings application will be the default value from the plist file, however, the NSUserDefaults API will still return nil .

Unfortunately, this means that if the default value makes sense (for example, the default web service URI is " http://www.example.com "), it must exist twice in my project: by default in plist and in my program code:

Root.plist:

  <dict> <key>Key</key> <string>mySettingKey</string> <key>Title</key> <string>Some address</string> <key>Type</key> <string>PSTextFieldSpecifier</string> <key>DefaultValue</key> <string>http://www.example.com</string> <key>IsSecure</key> <false /> <key>KeyboardType</key> <string>Alphabet</string> </dict> 

Program.swift:

 let ud = NSUserDefaults.standardUserDefaults() ud.synchronize() var mySettingValue = ud.stringForKey("mySettingKey") if mySettingValue == nil { mySettingValue = "http://www.example.com" } 

It is amazing.

+7
source

You must register your default settings so that they sync. source from here

 // Swift 3 var appDefaults = Dictionary<String, AnyObject>() appDefaults["mySettingKey"] = "http://www.example.com" // Default Value UserDefaults.standard.register(appDefaults) UserDefaults.standard.synchronize() let mySettingValue = UserDefaults.standard.string(forKey: "mySettingKey") 

Keep in mind that you should also use registerDefaults: when your application uses a set of settings. Since you already specified default values ​​inside the plists parameter set, you can expect your application to pick them up automatically. However, it is not. The information contained in the settings is read only by iOS Settings.app and is never supported by your application. In order for your application to use the same default values ​​as in Settings.app, you must manually copy the user's default keys and their default values ​​to a separate plist file and register it with the default database, as shown above.

+7
source

Default values ​​can be taken from Settings.bundle and added to UserDefaults. The following function can be called in AppDelegate.swift from didFinishLaunchingWithOptions .

 func setDefaultsFromSettingsBundle() { //Read PreferenceSpecifiers from Root.plist in Settings.Bundle if let settingsURL = Bundle.main.url(forResource: "Root", withExtension: "plist", subdirectory: "Settings.bundle"), let settingsPlist = NSDictionary(contentsOf: settingsURL), let preferences = settingsPlist["PreferenceSpecifiers"] as? [NSDictionary] { for prefSpecification in preferences { if let key = prefSpecification["Key"] as? String, let value = prefSpecification["DefaultValue"] { //If key doesn't exists in userDefaults then register it, else keep original value if UserDefaults.standard.value(forKey: key) == nil { UserDefaults.standard.set(value, forKey: key) NSLog("registerDefaultsFromSettingsBundle: Set following to UserDefaults - (key: \(key), value: \(value), type: \(type(of: value)))") } } } } else { NSLog("registerDefaultsFromSettingsBundle: Could not find Settings.bundle") } } 
+7
source

Source: https://habr.com/ru/post/1245881/


All Articles