8
votes

Is it possible to save and load data on Today Extension using NSUserDefaults? After closing the Notification Center, the widget behaves like an app which is terminated, so any data results lost. How could I solve this issue?

This is my code:

NSUserDefaults *defaults;

- (void)viewDidLoad {

[super viewDidLoad];

defaults = [NSUserDefaults standardUserDefaults];
NSArray *loadStrings = [defaults stringArrayForKey:@"savedStrings"];

if ([loadStrings objectAtIndex:0] != nil) {
    [display setText:[NSString stringWithFormat:@"%@", [loadStrings objectAtIndex:0]]];
}
if ([loadStrings objectAtIndex:1] != nil) {
    calculatorMemory = [NSString stringWithFormat:@"%@", [loadStrings objectAtIndex:1]].doubleValue;
}

}


- (IBAction)saveData:(id)sender {

NSString *displayString;
NSString *memoryString;

NSArray *saveStrings = [[NSArray alloc] initWithObjects: displayString, memoryString, nil];


defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:saveStrings forKey:@"savedStrings"];
[defaults synchronize];


}
5

5 Answers

19
votes

You need to use app group identifier instead of com.* For instance:

NSUserDefaults *shared = [[NSUserDefaults alloc]initWithSuiteName:@"group.company.appgroup"];

Don't forget to synchronise when you store data

[shared synchronize];
2
votes

You need to add the App Group stuff detailed under here and then if it actually worked (pretty iffy under beta) it should allow you to share NSUserDefault data like normal between the host and widget.

Edit: Normal NSUserDefaults does not work. Apple has implemented a new method. To use, simply redefine your NSUserDefaults instance like this:

NSUserDefaults *shared = [[NSUserDefaults alloc]initWithSuiteName:@"com.you.app.container"];
2
votes

For anyone wondering how in the world do you save and get values then look at this code.

In your regular app add this to save whatever you like in your *.m file.

NSUserDefaults *shared = [[NSUserDefaults alloc]initWithSuiteName:@"group.yourcompanyname.TodayExtensionSharingDefaults"];

    //save dic
    [shared setObject:dictionary2 forKey:@"dicForTodayWidget"];

    //save array
    [shared setObject:tempArray2 forKey:@"arrayForTodayWidget"];

    //save some value
    [shared setObject:@"1234" forKey:@"myValForTodayWidget"];

    [shared synchronize];

In your today widget under TodayViewController.m in viewDidLoad add this.

NSUserDefaults *shared = [[NSUserDefaults alloc]initWithSuiteName:@"group.yourcompanyname.TodayExtensionSharingDefaults"];

    //get dic
    NSMutableDictionary *dictionary = [shared objectForKey:@"dicForTodayWidget"];
1
votes

You first need the App Groups set up for both targets (application and the extension).

Then, use the

NSUserDefaults *shared = [[NSUserDefaults alloc]initWithSuiteName:@"group.company.myapp"];

to obtain the defaults object which you can read from/write to as usual.

If you want to be notified of changes to the defaults, use the NSUserDefaultsDidChangeNotification in your widget (or app).

For a step-by-step tutorial explaining all this, take a look at this blog post.

-2
votes

@edukulele Today Extension and Main app run on two processes. Today Extension can't receive NSUserDefaultsDidChangeNotifications. I tried use MMWormhole. It is very good.