NSUserDefault 无法在 iOS8 的扩展中保存和加载

Posted

技术标签:

【中文标题】NSUserDefault 无法在 iOS8 的扩展中保存和加载【英文标题】:NSUserDefault can't save & load in Extension in iOS8 【发布时间】:2014-06-16 12:49:00 【问题描述】:

我需要在我的 ios 自定义键盘中将数据保存到 NSUserDefault。 我已经在开发者门户和XCode 中成功创建了应用组和权利。

这是我使用 UISwitch 保存价值的方法

- (IBAction)switchAction:(id)sender

    [self.defaults setBool:self.myKey.on forKey:@"myValue"];

    [self.defaults synchronize];

这是我在 KeyboardView 中加载值的方式。

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

if([self.defaults boolForKey:@"myValue"])

    self.backgroundColor = [UIColor redColor];


else

    self.backgroundColor = [UIColor blackColor];

它不起作用并且不加载值。

如何保存和加载数据?

【问题讨论】:

Communicating and persisting data between apps with App Groups的可能重复 没有。我已经发现了这些问题。我的问题是我不知道如何从 NSUserDefault 加载数据。 我指的是my answer to that question,我在下面稍作修改和复制。 【参考方案1】:

在应用组中的所有应用程序中像这样初始化您的NSUserDefaults 对象,它们将共享数据库:

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

请记住,每个应用程序的 [NSUserDefaults standardUserDefaults] 数据库中的所有内容都不会转移到此数据库中。

[NSUserDefaults standardUserDefaults] 应该像上面的代码一样返回共享数据库的documentation indicates,但事实并非如此。我将此作为错误提交 (rdar://17164758)。

别忘了同步数据库:

[yourDefaults synchronize];

【讨论】:

是的,我确实像你说的那样,它没有正确加载。这是我的代码。 self.defaults = [[NSUserDefaults alloc] initWithSuiteName:@""]; if([self.defaults boolForKey:@"myValue"]) self.backgroundColor = [UIColor redColor]; else self.backgroundColor = [UIColor blackColor]; @Sabo 数据库一开始是空的,所以你必须在设置任何值之前调用你的switchAction: 方法。还要确保在您的权利文件、开发人员门户应用 ID、配置文件和 Xcode 中正确设置您的应用组。 我的 SwitchAction 是与 UISwitch 的连接事件,当 UISwitch 打开时,我将值保存到 NSUserDefault。但是我无法在 KeyboardView 中加载该数据。 :( @Sabo 还要确保在您的权利文件、开发人员门户应用程序 ID、配置文件和 Xcode 中正确设置您的应用程序组。确保您在扩展程序和应用程序本身中都使用initWithSuiteName:@"<group identifier>" 添加到您的答案中。您还必须在应用扩展的 Info.plist 中设置 RequestsOpenAccess = YES。它应该在 NSExtension->NSExtensionAttributes 下(您必须使用类型字典创建它)-> RequestsOpenAccess (Boolean) == YES。只有在此之后,我的应用扩展才能访问应用组的 NSUserDefaults。【参考方案2】:

好的,所以我环顾四周,因为我遇到了确切的问题。我所做的是将主应用程序和扩展添加到一个组中,转到主项目->目标->功能并创建一个组(如果你没有,或者无论如何创建一个组),如下所示:

然后,转到目标 (E) 下方的扩展,再次转到 Capabilities 并将扩展添加到组(与您为主要目标所做的完全相同的应用组),如下所示:

然后,一旦你完成了这两个,在你的主应用程序中,每当你想添加一些东西时,创建一个新的 NSUserDefaults 实例,但 Suitename 等于你之前创建的组名。像这样:

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.

在你的扩展的 ViewController 中,使用相同的组名但读取用户默认值:

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

还有,瞧!数组在那里!我在某处读到,您甚至可以使用 Wormhole 类在对象更改时添加通知功能,但我找不到指向它的链接。我敢肯定,如果你用谷歌搜索虫洞课程,你会遇到它。

希望我能帮上忙,如果您发现了更多信息,请与我分享。

【讨论】:

【参考方案3】:

您可以从包含应用程序中加载正确的数据,因此在扩展应用程序中设置一个新值可能会有所帮助。

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

然后加载正确的数据。

【讨论】:

以上是关于NSUserDefault 无法在 iOS8 的扩展中保存和加载的主要内容,如果未能解决你的问题,请参考以下文章

从 NSUserDefault 保存和检索数据时,保存按钮无法正常工作

写入 NSUserDefault 和 .plist 失败

如何在 appdelegate 中使用 applicationDidEnterBackground 保存 NSUserDefault

使用 Alamofire 时如何将令牌存储在 NSUserDefault 中?

Keychain 和 NSUserDefault 的区别?

Swift 问题 - NSUserDefault 和 Settings Bundle 没有响应