Write into Settings bundle in Swift
Asked Answered
G

1

6

I have created an app with settings bundle in it and the app configuration can be changed. Reading from Settings bundle is done. I am using below code.

    let defs: NSUserDefaults = NSUserDefaults.standardUserDefaults()
    defs.synchronize()

    var settingsBundle: NSString = NSBundle.mainBundle().pathForResource("Settings", ofType: "bundle")!
    if(settingsBundle.containsString("")){
        NSLog("Could not find Settings.bundle");
        return;
    }
    var settings: NSDictionary = NSDictionary(contentsOfFile: settingsBundle.stringByAppendingPathComponent("Root.plist"))!
    var preferences: NSArray = settings.objectForKey("PreferenceSpecifiers") as! NSArray
    var defaultsToRegister: NSMutableDictionary = NSMutableDictionary(capacity: preferences.count)

    for prefSpecification in preferences {
        if (prefSpecification.objectForKey("Key") != nil) {
            let key: NSString = prefSpecification.objectForKey("Key")! as! NSString
            if !key.containsString("") {
                let currentObject: AnyObject? = defs.objectForKey(key as! String)
                if currentObject == nil {
                    // not readable: set value from Settings.bundle
                    let objectToSet: AnyObject? = prefSpecification.objectForKey("DefaultValue")

                    var objectKey : String = key as! String
                    var finalObject : String = objectToSet as! String

                    defaultsToRegister.setObject(finalObject, forKey: objectKey)
                }else{
                    //already readable: don't touch
                    var objectKey : String = key as! String
                    var finalObject : String = currentObject as! String

                    defaultsToRegister.setObject(finalObject, forKey: objectKey)
                }
            }
        }
    }
    defs.registerDefaults(defaultsToRegister as [NSObject : AnyObject])
    defs.synchronize()

The same settings can be updated the app itself. But how I can write the updated values into the Settings bundle? In this link, the accepted answer says it is possible using NSUserDefaults. But I couldn't, someonce can please help?

EDIT Please check below for more info:

{
PreferenceSpecifiers =     (
            {
        Title = Group;
        Type = PSGroupSpecifier;
    },
            {
        DefaultValue = Test1;
        Key = "multi_values";
        Title = "Multiple Values";
        Titles =             (
            FIrst,
            Second,
            Third
        );
        Type = PSMultiValueSpecifier;
        Values =             (
            FirstValue,
            SecondValue,
            ThirdValue
        );
    }
);
StringsTable = Root;

}

I am having a Settings bundle like above format and I am able to read it in the app. But how can I update this multi values selection as per I make the changes in the app? I used the following code to update the Title value.

     var settings: NSDictionary = NSDictionary(contentsOfFile: settingsBundle.stringByAppendingPathComponent("Root.plist"))!
    var preferences: NSArray = settings.objectForKey("PreferenceSpecifiers") as! NSArray


    preferences.objectAtIndex(1).setValue("MutipleValue is updated", forKey: "Title")

    settings.setValue(preferences, forKey: "PreferenceSpecifiers")

    settings.writeToFile(settingsBundle.stringByAppendingPathComponent("Root.plist"), atomically: false)
Glad answered 18/9, 2015 at 6:33 Comment(0)
D
8

In link that you provided has answer to your question

Note that you shouldn't read from the settings bundle directly, as it makes no sense. You should always fetch and set user defaults using NSUserDefaults. When the user makes a change in the settings application, NSUserDefaults will reflect this automatically. They will always be kept in sync.

When you create a new item in settings.bundle, you should set it identifier.

After that, you can get required value with NSUserDefaults by following way:

if let export_enabled = NSUserDefaults.standardUserDefaults().valueForKey("export_enabled") as? Bool
{
    if let export_interval = NSUserDefaults.standardUserDefaults().valueForKey("export_interval") as? Number
    {
        // ...
    }
}

And change:

NSUserDefaults.standardUserDefaults().setValue(true, forKey: "export_enabled")

Update

iOS application on device has the following structure:

AppTitle.app
    AppTitle
    AppTitleIcon.png
    Info.plist
    com.company.apptitle.plist (read/write)
    settings.bundle (readonly)

Settings.bundle intended for forming configuration hierarchy in the default Settings.app. It contains titles of sections and settings types, but settings values are stored in com.company.apptitle.plist.

Because settings.bundle is read-only, you cannot change its structure or section titles. You can only change settings values and this change occurs in com.company.apptitle.plist via NSUserDefaults.

Doubt answered 18/9, 2015 at 9:5 Comment(2)
Thanks for your reply. For better understanding of my issue I have updated my question. Could you please check it now?Glad
I am having a similar issue. I can read the default setting that can be changed via the iPhone Watch app settings page But if I try to set any value from my watch app and save it to the default the setting page on the iPhone app does not reflect the new selection. It’s seams to be one way communication.Thormora

© 2022 - 2024 — McMap. All rights reserved.