Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSUserDefault can't save & load in Extension in iOS8

I need to save data to NSUserDefault in my iOS Custom Keyboard. I have successfully created App Groups and entitlement in developer portal and XCode.

Here is how i save my value with UISwitch

- (IBAction)switchAction:(id)sender
{
    [self.defaults setBool:self.myKey.on forKey:@"myValue"];

    [self.defaults synchronize];
}

and here is how i load value in KeyboardView.

self.defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.mycompany.customkeyboard"];

if([self.defaults boolForKey:@"myValue"])
{
    self.backgroundColor = [UIColor redColor];
}

else
{
    self.backgroundColor = [UIColor blackColor];
}

It's doesn't work and doesn't load value.

How can i save and load data?

like image 684
Fire Fist Avatar asked Jun 16 '14 12:06

Fire Fist


2 Answers

Initialize your NSUserDefaults object like this in all applications in the app group and they will share the database:

[[NSUserDefaults alloc] initWithSuiteName:@"group identifier"];

Keep in mind everything from the [NSUserDefaults standardUserDefaults] database for each application will not carry over into this database.

The documentation indicates that [NSUserDefaults standardUserDefaults] should return the shared database like the above code does, however it does not. I filed this as a bug (rdar://17164758).

And don't forget to synchronize the database:

[yourDefaults synchronize];
like image 69
Andrew Avatar answered Nov 12 '22 03:11

Andrew


Ok, So I had a look around becuase I had the exact problem. What I did that worked was to add the main app and the extension to a group, Go to main project->Target->Capabilities and create a group (if you don't have one, or make one anyway) like this:

enter image description here

Then, go to the Extension below the target (E), again to Capabilities and add the extension to the group (exactly the same app group as you did for the main target), like this:

enter image description here

Then, once you have done both, in your main app, whenever you want to add something, create a new instance of NSUserDefaults, but for the Suitename equal to the groupname you made earlier. Like this:

NSArray *testing = @[@"first",@"Second",@"Third"];
NSUserDefaults *userd = [[NSUserDefaults alloc]initWithSuiteName:@"The gouprname I made earlier"];//This is exactly the same as the groupname
[userd setObject:testing forKey:@"ExtensionArray"];//set the object you want to share
[userd synchronize]; //It's a good idea to sync, just to be on the safe side.

In your extension's ViewController, use the same group name but to read the user defaults:

NSUserDefaults *sharedD=[[NSUserDefaults alloc]initWithSuiteName:@"Exactly the same groupname that I gave both in the Capabilities and when initialising the userdefault"];
self.testing = [[NSArray alloc]initWithArray:[sharedD arrayForKey:@"ExtensionArray"]];

And Voila! the array is there! I read somewhere that you can even add notification functionality for when the object changes, using a Wormhole class, but I can't find the link to it. I'm sure if you google for Wormhole class, you'll come across it.

I hope I could help, and if you found any more info, please share it with me.

like image 33
Septronic Avatar answered Nov 12 '22 03:11

Septronic