Fire Fist
Fire Fist

Reputation: 7060

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?

Upvotes: 5

Views: 4653

Answers (3)

Septronic
Septronic

Reputation: 1176

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.

Upvotes: 2

xionggai
xionggai

Reputation: 1

You could load the right data from the containing app, so maybe set a new value in extension app will help.

[self.defaults setObject:newValue forKey:@"thisKeyIsJustUsedForSyn"]

And then load the right data.

Upvotes: 0

Andrew
Andrew

Reputation: 15377

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

Upvotes: 4

Related Questions