为啥 NSUserDefaults 在我的应用程序和共享扩展程序之间不起作用?

Posted

技术标签:

【中文标题】为啥 NSUserDefaults 在我的应用程序和共享扩展程序之间不起作用?【英文标题】:Why doesn't NSUserDefaults work between my app & share extension?为什么 NSUserDefaults 在我的应用程序和共享扩展程序之间不起作用? 【发布时间】:2016-10-11 16:43:05 【问题描述】:

我有一个带有共享扩展的 ios 应用。我正在尝试使用 NSUserDefaults 和 App Groups 在它们之间共享数据,但是,虽然我可以写入 NSUD 对象、读取它和 synchronize() 而不会出错,但读取扩展名总是会导致 nil

我有一个应用程序组,即文字字符串“group.net.foo.bar”,应用程序和扩展程序都已在 Capabilities -> App Groups 下为其配置。此字符串在我的应用程序的常量结构中:

struct Forum 
    static let APP_GROUP = "group.net.foo.bar"
    static let AUTH_KEY = "AUTH_KEY"

在主应用程序中,我创建了一个 UserDefaults 对象并写入它:

fileprivate lazy var userDefaults: UserDefaults = 
    let defaults = UserDefaults()
    defaults.addSuite(named: Forum.APP_GROUP)
    return defaults
()

// later
userDefaults.set(apiKey, forKey: Forum.AUTH_KEY)
userDefaults.synchronize()

synchronize() 之后创建一个新的 NSUD 对象并检索 AUTH_KEY 有效。在扩展中,我创建了一个 NSUD 并尝试检索该值,但无济于事:

private lazy var userDefaults: UserDefaults = 
    let defaults = UserDefaults()
    defaults.addSuite(named: Forum.APP_GROUP)
    return defaults
()

// later
private func getApiKey() -> String? 
    return userDefaults.string(forKey: Forum.AUTH_KEY)

// returns nil

在我阅读 Apple 文档和 Stack Overflow 上令人沮丧的类似问题时,我无法判断我做错了什么。

Xcode 版本 8.0 (8A218a),也使用 Xcode 8.1 Beta 2 进行了测试。在模拟器和运行 iOS 10 的 iPhone 6s 上的行为相同。

【问题讨论】:

【参考方案1】:

不确定defaults.addSuite(named: ...) 是否与UserDefaults(suiteName: ...) 相同。在我的应用中,我以这种方式使用 appGroups,它按预期工作:

// write
if let userDefaults = UserDefaults(suiteName: appGroupName) 
    userDefaults.set("---" as AnyObject, forKey: "distance")
    userDefaults.set("---" as AnyObject, forKey: "altitude")
    ...
    userDefaults.synchronize()


// read
if let userDefaults = UserDefaults(suiteName: appGroupName) 
    self.distanceLabel.text = userDefaults.string(forKey: "distance")
    self.altitudeLabel.text = userDefaults.string(forKey: "altitude")

【讨论】:

太棒了,就是这样。知道defaults.addSuite(named: ...) 是干什么用的吗? 很高兴为您提供帮助。如上所述,我不确定。这里的文档有些混乱。 确实——我想我被绊倒了,因为我发现的所有当前示例都是使用 initWithSuiteName 的 ObjC 或 Swift 2.3。 Swift 3.0 重命名了这个,我认为 userDefaultsObject.addSuite(named: …) 是我看到的最接近的东西,我错过了重命名的构造函数。 我已按照问题和上述答案中给出的所有步骤进行操作..在获得价值的同时我仍然收到 nil..【参考方案2】:

如果您在尝试使用 userDefault 将数据保存到扩展 APP 时遇到此问题,可能是您编写了以下代码:[[NSUserDefaults standardUserDefaults] initWithSuiteName:@"group.xxx.com" ];,此代码重置默认用户默认值。实际上,正确的代码是: [[NSUserDefaults alloc] initWithSuiteName:@"group.xxx.com"]; enter link description here

【讨论】:

以上是关于为啥 NSUserDefaults 在我的应用程序和共享扩展程序之间不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的应用加载之前从 NSUserDefaults 检索值...?

为啥在创建 UIWebView 后清除 NSUserDefaults 会导致 EXC_CRASH?

为啥在 iOS 中使用 NSUserDefaults?

UIImage 没有从 NSUserDefaults 中检索

如果我没有进行更改,为啥我需要同步 NSUserDefaults?

应用程序委托和视图控制器之间的 NSUserDefaults