3

I am using Settings bundle to configure my app. As a side effect, the same set of settings is available outside the app in iOS Settings. This is great. However there is a little problem - I do need to react to the changes. For example, I have a name that a user is using to be recognized by others and if it changes, a server call must happen. How to handle that?

EDIT: take it easy, fellas. I've never done that before and it's hard to read thru all guidelines available. Settings.bundle is not an obvious thing to deal with. Anyways, feel free to vote the question down but at least take a minute and read thru all commends before you do so.

Tried a couple suggested ways, i.e. using notifications and in more direct manipulation of defaults when app becomes active. The second approach worked better because it only executed at times I expect instead of every time any config setting is changed/added/deleted within the app.

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSString *nameOld = [[NSUserDefaults standardUserDefaults] stringForKey:kNameKey];

    [[NSUserDefaults standardUserDefaults] synchronize];

    NSString *nameNew = [[NSUserDefaults standardUserDefaults] stringForKey:kNameKey];
Schultz9999
  • 8,717
  • 8
  • 48
  • 87
  • Check the value. Compare to a saved version elsewhere in defaults. – Wain Nov 25 '13 at 21:52
  • Not sure who downvoted... I am absolutely aware of how to add an observer. That's a clear technique. I was wondering about getting back from iOS Settings screen. I thing @Duncan Groenewald gave me an idea. – Schultz9999 Nov 25 '13 at 21:59
  • @MartinR I am not sure why this is a dup. There is nothing in that question that addresses my issue. Nor nothing is said here https://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/UserDefaults/Preferences/Preferences.html. So please elaborate. – Schultz9999 Nov 25 '13 at 22:09
  • @Schultz9999: Your question was how to react to changes in the app settings, and that can be done by listening to the NSUserDefaultsDidChangeNotification. There is also a sample app demonstrating the technique: https://developer.apple.com/LIBRARY/IOS/samplecode/AppPrefs/Introduction/Intro.html. - But I am sorry if I misunderstood your question ... – Martin R Nov 25 '13 at 22:20
  • @MartinR Now yes, you are right. That is the best way. And the question is really a dup. I'll vote myself for closing. – Schultz9999 Nov 25 '13 at 22:28
  • @MartinR Found this one with some details: http://stackoverflow.com/questions/3166563/how-to-receive-nsuserdefaultsdidchangenotification-iphone. This may be one that mine dups. – Schultz9999 Nov 25 '13 at 22:35

1 Answers1

2

You should check for changes to settings in this appDelegate method.

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Check for any changes to settings
    [[NSUserDefaults standardUserDefaults] synchronize];
    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
    bool userICloudChoice = [userDefaults boolForKey:_cloudPreferenceKey];
}
Duncan Groenewald
  • 8,496
  • 6
  • 41
  • 76
  • Ah.. So get an old value before sychronizing and then sync and get a new one? – Schultz9999 Nov 25 '13 at 21:56
  • @0x7fffffff Copy of the whole NSUserDefaults? I guess I can for there is a method to represent it as a dictionary. – Schultz9999 Nov 25 '13 at 22:00
  • I just call synchronise because I found that if the user makes changes to app settings in the Settings bundle (using iOS Settings app) then unless I call synchronise the app does not always see these changes immediately. So I assumed (perhaps incorrectly) that you want to be able to detect when the user makes changes to app settings using the iOS Settings app in your app and then respond accordingly. – Duncan Groenewald Nov 25 '13 at 22:03
  • That's correct. User name or, say, ordering require some reaction when app is going back to foreground. I'll play with sync and see if I can avoid creating a copy as 0x7fffffff suggested. – Schultz9999 Nov 25 '13 at 22:08
  • 1
    I would not rely on synch, I keep the settings in memory in the app and compare against the ones retrieved each time the app returns to the foreground. – Duncan Groenewald Nov 25 '13 at 22:10
  • So you have an in-memory global dictionary and they you use `registerDefaults`? I guess it's reasonable. The only problem I could see is when app crashes and then settings are changed externally. Edge case but yet. Termination is OK because you can sync settings in the corresponding delegate. – Schultz9999 Nov 25 '13 at 22:21
  • When the app loads I get the settings using the same calls above. I am not sure what you mean by registerDefaults ? I use the following to save the settings from within the app [userDefaults setObject:version forKey:@"version"]; – Duncan Groenewald Nov 25 '13 at 22:27
  • BTW how do you shade text in comments? Like you did with registerDefaults ? – Duncan Groenewald Nov 25 '13 at 22:28
  • Use back ampersand (under tilde char or ESC key on my mac) as quotation marks. – Schultz9999 Nov 25 '13 at 22:31
  • OK yes you would use registerDefaults and synchronise to save the NSDictionary of settings, I do them one setting at a time... – Duncan Groenewald Nov 25 '13 at 22:31
  • Tried both ways, Notification and what you suggested. Notification works but it fires up for all single little change I make within app and I don't like that. Your approach works well and has expected (at least for me) behavior... And people keep voting me down :) – Schultz9999 Nov 26 '13 at 00:14
  • They don't see the bigger picture I guess. – Duncan Groenewald Nov 26 '13 at 01:23
  • As an addendum, this also fixed an issue for me where a preference was changed in settings.app, and the app wouldn't recognize the setting had changed when coming into the foreground until the 2nd, 3rd, or 4th time the app would enter foreground. I assume Settings.bundle doesn't run synchronize for every change. Forcing this sync when entering foreground ensures that all settings changed while the app is in background are available immediately. – jlindenbaum Jul 20 '14 at 17:50