将数组存储在WidgetKit的应用组上

问题描述

我正在尝试将结构数组存储到应用程序组容器中,以便以后在小部件上使用它。 假设我有一个字符串数组

let = array = ["object1","object2","object3"]

并且我在这里看到了我可以访问应用程序组容器的网址

let applicationGroupId = "group.com.development.widget"
            
guard let groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: applicationGroupId) else {
    fatalError("Could not get shared app group directory.")
}

现在,我需要知道如何将该数组存储在应用程序组上以及如何从Widgetkit SwiftUI类中读取它

您的帮助将不胜感激。

解决方法

签名,功能和权利

现在,应该可以在Xcode(12+)中完成所有这些操作。在应用程序的项目设置中,转到“签名和功能”选项卡,并确保启用了“自动管理签名” ,并且该团队拥有有效的开发团队(公司或个人帐户)。

点击

点击左上角的 + Capability 按钮以输入App Group Capability(这还将添加一个权利文件)。现在,您将找到“应用程序组”部分。点击 App Groups 的+按钮,然后输入一个全局唯一标识符(例如group.<appid>)。这将在开发人员平台上创建应用程序组,并将其添加到您应用程序的配置文件和权利中。

您必须重复相同的步骤并对所有目标(应用程序目标,小部件扩展目标和(可选)意图目标)使用相同的应用程序组。如果您单击其他目标的应用程序组的重新加载按钮,它将自动显示您先前注册的应用程序组,您可以选中该复选框。如果没有,则按+并使用相同的ID也应该可以。

最后,检查所有权利文件,并确保它们在应用程序组中具有相同的字符串(仅复制并粘贴以确保内容)。

代码

在代码中,您现在只需要使用所选的应用组作为suitName来访问用户默认设置。要测试所有设置是否正确,我将以下行放在application(_:didFinishLaunchingWithOptions)中:

UserDefaults(suiteName: "group.id.test")!.setValue(["object1","object2","object3"],forKey: "test")

在窗口小部件中,只需尝试将其置于文本视图中即可:

struct WidgetTestEntryView : View {
  var entry: Provider.Entry
  var text: String {
      (UserDefaults(suiteName: "group.id.test")!.value(forKey: "test") as? [String])?.joined(separator: " ") ?? "Nothing stored yet"
  }

  var body: some View {
    Text(text)
  }
}

注意:我强行拆开用户默认设置以尽早失败,并检查功能/签名设置是否有效。在生产中,您应该防止出现故障。

备用存储

正如您所指出的,通过写入FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:)提供的url,也可以将数据持久保存在共享容器中,但我认为您的简单示例不需要这样做。如果您要共享比StringIntArray更复杂的数据,请确保将其转换为Data,因为用户默认无法处理任意数据(即使是Codable)。

手动签名

如果您使用手动签名,则只需在开发人员控制台中执行相同的步骤,即从注册应用程序组开始。之后,将该组添加到所有标识符的功能,然后重新创建所有供应配置文件。从那里应该使用与上述步骤类似的步骤。