NSUserDefaults:转储NSUserDefaults的standardUserDefaults结构

17

有人知道通过NSLog快速转储NSUserDefaults的standardUserDefaults吗?这是我的代码:

NSLog(@"NSUserDefaults dump: %@", [NSUserDefaults standardUserDefaults]);

但它返回:

NSUserDefaults dump: <NSUserDefaults: 0x50b520>

......这不是我要找的。我真的想要键值对。

任何帮助或指引都将不胜感激。谢谢!

6个回答

36
NSLog(@"NSUserDefaults dump: %@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);

@rpetrich:谢谢。我把它放进去了,确实把输出转储到调试器的控制台了,但是转储出来的信息看起来更像是系统特定的用户默认设置,包括打印机首选项、时区首选项等等...你知道在iPhone上只提取应用程序特定的userDefaults的方法吗?Kevin - Kevin Bomberry
1
NSUserDefaults 存储在 /User/Applications/{UNIQUE_ID}/Library/Preferences/com.yourcompany.yourapp.plist;您应该能够通过检索 [[NSBundle mainBundle] bundlePath] 并向上导航一级来获取到 {UNIQUE_ID} 的路径,但我不建议依赖该文件在操作系统版本之间保持在同一位置。 - rpetrich
另外,如果您需要在编译时不知道数量的键,则应将它们存储在NSDictionary中,然后将其存储在NSUserDefaults中,以避免与Apple的设置发生冲突。 - rpetrich
是啊,我在看那份转储文件的时候也在考虑这个问题。如果可能的话,我真的不想覆盖掉一个苹果键值对。 - Kevin Bomberry

19

感谢我的商业伙伴和朋友 Don McCaughey,为我修复了代码并提供了简洁明了的答案。以下是一个代码片段,与大家分享:

  NSDictionary *bundleInfo = [[NSBundle mainBundle] infoDictionary];
  NSString *bundleId = [bundleInfo objectForKey: @"CFBundleIdentifier"];

  NSUserDefaults *appUserDefaults = [[NSUserDefaults alloc] init];
  NSLog(@"Start dumping userDefaults for %@", bundleId);
  NSLog(@"userDefaults dump: %@", [appUserDefaults persistentDomainForName: bundleId]);
  NSLog(@"Finished dumping userDefaults for %@", bundleId);
  [appUserDefaults release];

正如你所看到的,每个回答问题的人都走在正确的轨道上,但是没有任何代码能够解决问题 - 直到唐在源代码控制中编辑了我们的代码。感谢大家!


辉煌。这需要在答案列表中排名更高。 - Alex Zavatone

9

尝试:

NSLog(@"NSUserDefaults dump: %@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);

dictionaryRepresentation方法返回默认设置的NSDictionary表示。


@thesamet:也感谢你。就像你们两个在传递相同的iPhone开发精神一样。(^_^)请看看我对rpetrich的回复,也许你会更快地得到答案。(^_^)再次感谢! - Kevin Bomberry
1
请检查您在info.plist中是否设置了应用程序包标识符。 - thesamet

8
NSLog(@"%@ defaults = %@", [self class], 
  [[NSUserDefaults standardUserDefaults] 
   persistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]]);

6

共享的NSUserDefaults默认使用三个搜索域进行初始化(如果需要,您也可以添加其他搜索域):应用程序参数、应用程序首选项(存储在应用程序 plist 中的内容)和本地化系统首选项。最后一个是为什么您会看到那些陌生的苹果键,但您真的不必担心“覆盖”它们。如果您使用相同的键名,它只会将该值放入应用程序首选项域中。应用程序的首选项会在系统首选项之前搜索,因此您将得到相同的值,但不会影响其他任何内容。

如果您确实只想要您的应用程序首选项,您可以删除其他搜索域(具体名称可以在文档中找到)。


嘿,谢谢Marc。你能指点我如何修改代码的方向吗: NSLog(@"NSUserDefaults dump: %@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]); ...以仅搜索应用程序的userDefaults吗? - Kevin Bomberry
1
在调用dictionaryRepresentation之前,您需要删除其他搜索域(我认为方法类似于removeSuiteNamed:?)。 我不记得域名,但您可以在NSUserDefaults文档中找到它们。 - Marc Charbonneau

1

这里有一个方便的类,可以用来转储各种东西:

https://github.com/VTPG/CommonCode/blob/master/VTPG_Common.h

要使用它,将标题添加到您的“m”中。保留HTML,不要解释。
#import "VTPG_Common.h"

在你的类中的任何地方调用LOG_EXPR(foo):

NSUserDefaults *userDefaults = [[NSUserDefaults alloc] init];
[userDefaults addSuiteNamed:@"com.apple.spaces"];
NSDictionary *foo = [userDefaults dictionaryForKey:@"SpacesDisplayConfiguration"];
LOG_EXPR(foo);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接