8

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];


}
Andrew
  • 15,357
  • 6
  • 66
  • 101
Massimo Piazza
  • 663
  • 3
  • 7
  • 21
  • possible duplicate of [Communicating and persisting data between apps with App Groups](http://stackoverflow.com/questions/24015506/communicating-and-persisting-data-between-apps-with-app-groups) – Andrew Jun 09 '14 at 15:21

5 Answers5

19

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];
Andrew
  • 15,357
  • 6
  • 66
  • 101
GondyB
  • 423
  • 3
  • 10
  • Thanks, however after reading more deeply the documentation, two days ago I solved the problem as you wrote! – Massimo Piazza Jun 09 '14 at 14:32
  • @MassimoPiazza I have followed steps and this does not work. I am working with keyboard app extension. Thoughts? – Spentak Jul 07 '14 at 22:33
  • @Spentak did you enable App group in xcode project capabilities for both containing app and keyboard extension ? – GondyB Jul 08 '14 at 07:26
  • @BenjG37 yes I did. Is it possible that user defaults are not working for keyboard extensions yet? – Spentak Jul 08 '14 at 14:59
  • 4
    Great tutorial on this topic http://www.glimsoft.com/06/28/ios-8-today-extension-tutorial/ – CVertex Sep 09 '14 at 07:30
  • @Spentak : Have you get this working for keyboard extension? I am following same procedure but not working for me as well. – Muzammil Sep 25 '14 at 08:33
  • damm... it is not working for me i am trying from last 2 days in ios 9.1 – Patel Jigar Nov 17 '15 at 09:37
2

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"];
Allison
  • 2,213
  • 4
  • 32
  • 56
  • @BalestraPatrick Make sure app groups are configured correctly and the correct entitlements are configured for both your app target and your extension target, as well as in your App IDs and provisioning profiles. – Andrew Jun 09 '14 at 15:24
  • 1
    This does not appear to work on iOS Keyboard Extensions – Spentak Jul 10 '14 at 18:57
2

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"];
Sam B
  • 27,273
  • 15
  • 84
  • 121
1

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.

Lukas Petr
  • 1,513
  • 16
  • 19
  • followed tutorial and does not work with keyboard app extension – Spentak Jul 07 '14 at 22:31
  • @Spentak well that's weird. What exactly isn't working? Also, the tutorial (as well as this SO question) is about Today extensions, the keyboard ones are much more limited - maybe they have some limit on NSUserDefaults or something. – Lukas Petr Jul 10 '14 at 12:06
  • Lukas - can you get user defaults working on a keyboard extension? I have tested it and cannot make a successful test case. – Spentak Jul 10 '14 at 18:51
  • 2
    Have you tried working with `NSUserDefaultsDidChangeNotification`s? I don't receive notifications and it seems other people don't either, but I couldn't find any official documentation so I'm still wondering if this is possible somehow. – hagi Nov 28 '14 at 16:49
  • hagi - did you found a solution how to make `NSUserDefaultsDidChangeNotification` work? For me it is not working as well. I can check that values are changing from the main app to the extension and I checked it with the timer who triggers every second. But notifications does not appear even if the values was changed. I use groups, I use `initWithSuiteName` for user defaults initiation. And I can reach values. So everything is working except notifying. And I add notification center observer to my extension via `addObserver:selector:name:object:` with object value `nil`. But it is not working. – edukulele Jul 17 '15 at 11:09
-2

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

minus_one
  • 62
  • 1
  • 3
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/12773697) – Kara Jun 22 '16 at 16:45
  • My answer include this library. How to use library must visit this link.I think very easy.Now I already delete that link. – minus_one Jun 23 '16 at 06:02