在扩展之间共享 UserDefaults

Sharing UserDefaults between extensions

正在创建一个今日小部件,我正在使用 UserDefaults(suiteName:) 来保存一些数据。在主应用程序中,我使用 UserDefaults.standard()。这不能被扩展读取(或者可以?),这就是我使用 suiteName: 构造函数的原因。

用户在主应用程序中坚持 UserDefaults.standard() 的数据需要在扩展程序中可用。

这次我都在坚持,让价值观可以共享

 UserDefaults.standard().set:...forKey:...
 UserDefaults(suiteName:...)().set:...forKey:...
 ...

问题是我是否应该将 UserDefaults.standard() 全部删除并在我的应用程序中只使用 UserDefaults(suiteName:),或者这是不好的做法,如果是这样,为什么?

编辑:我正在使用应用程序组容器。为了澄清,我问我是否应该在整个项目中将 standard() 替换为 suiteName:

您不能使用 UserDefaults.standard 在宿主应用与其应用扩展之间共享数据。您必须使用 UserDefaults(suiteName:) 创建一个共享容器来共享数据。

Even though an app extension bundle is nested within its containing app’s bundle, the running app extension and containing app have no direct access to each other’s containers.

To enable data sharing, use Xcode or the Developer portal to enable app groups for the containing app and its contained app extensions. Next, register the app group in the portal and specify the app group to use in the containing app.

After you enable app groups, an app extension and its containing app can both use the NSUserDefaults API to share access to user preferences. To enable this sharing, use the initWithSuiteName: method to instantiate a new NSUserDefaults object, passing in the identifier of the shared group.

更多请参考:https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW1

如何使用应用程序组:https://github.com/pgpt10/Today-Widget

Standard 还是 SuiteName?

对仅适用于主机应用程序的数据使用标准一个。将 suiteName 用于要在扩展和主机应用程序之间共享的数据。只是不要在两者中保留相同的数据。避免数据冗余。两者结合使用。

创建共享包的简单示例:

if let userDefaults = UserDefaults(suiteName: "group.your.bundle.here") {
    userDefaults.set("test 1" as AnyObject, forKey: "key1")
    userDefaults.set("test 2" as AnyObject, forKey: "key2")
    userDefaults.synchronize()
}

这是您稍后可以阅读的方式:

if let userDefaults = UserDefaults(suiteName: "group.your.bundle.here") {
    let value1 = userDefaults.string(forKey: "key1")
    let value2 = userDefaults.string(forKey: "key2")
    ...
}

确保在功能 选项卡中为您的所有目标(您的应用程序和扩展程序目标)启用了App Groups

然后在创建时使用上面的组标识符作为套件名称UserDefaults:

let userDefaults = UserDefaults(suiteName: "group.com.YourCompany.YourApp")

还要确保将应用程序组添加到正确的配置(调试、发布)。如果您在 Debug 中为您的应用程序目标添加 App Groups 并尝试在您的扩展的 Release 配置中使用它,那么它不会工作。

如果您在调试配置(针对应用目标)中添加,则在调试配置(针对扩展目标)中使用它

PGDev:增强:

将设置(首选项)https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/UserDefaults/Preferences/Preferences.html 拖到扩展程序时,您无法避免冗余: 它们包含在应用程序私有包中,必须复制 进入 suitenamed bundle 以供应用程序扩展使用