开发者

Detecting changed user defaults

I have an iPhone app and have implemented local notifications. The app has a page in Settings that allows a user to schedule notifications a specified number of days in advance of an event. To make sure that changes to the settings take effect every time a user activates the app, I have the following in my app delegate:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[NSUserDefaults standardUserDefaults] synchronize];
    [self rescheduleAllNotificationsWithUserNotification:NO];
}

The problem is that the call to rescheduleAllNotificationsWithUserNotification: takes a few seconds and the app feels a little sluggish on start.

I only need to call rescheduleAllNotificationsWithUserNotification: if any of the settings have been changed. Is there a way to detect if the us开发者_运维百科er has changed any of the settings between app activations so I can avoid always rescheduling the notifications?


I think you might be looking for the NSUserDefaultsDidChangeNotification notification.

You can register to listen to this notification and be informed whenever the user's preferences change.


You should use a way to put this method call in another thread is possible. performSelectorInBackground is an easy way to do it:

[self performSelectorInBackground:@selector(rescheduleAllNotificationsWithUserNotification:) withObject:NO];

That should help you get rid of the laggy performance. You could even use ^blocks, as you seem to be on iOS 4.


What I have done in the past, if there are not too many preference values to monitor, is to have alternate versions, sort of "the last time I ran" versions. One set of values is accessible through the Settings application but the other is only set from within the application.

NSString *name = (NSString *) CFPreferencesCopyAppValue( (CFStringRef) @"name_preference", kCFPreferencesCurrentApplication );
NSString *nameLastTime = (NSString *) CFPreferencesCopyAppValue( (CFStringRef) @"name_last_execution", kCFPreferencesCurrentApplication );
// Need obvious checks for empty or missing entries, etc., etc.
if( ![nameLastTime isEqual: name] ) {
    // Store the new name as the name at last execution...
    CFPreferencesSetAppValue( (CFStringRef) @"name_last_execution", (CFStringRef) name, kCFPreferencesCurrentApplication );
    CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
    [self rescheduleAllNotificationsWithUserNotification:NO];
}

It is not real elegant with fancy object-oriented call-back methods, etc., but it gets the job done cheaply and reliably.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜