在iOS的SwiftUI中的主应用和小部件之间共享数据14 UserDefaults 文件容器 CoreData

问题描述

@main
struct ClockWidgetExt: Widget {
    private let kind: String = "ClockWidgetExt"
    
    public var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind,provider: Provider(),placeholder: PlaceholderView()) { entry in
            HomeTestView()
        }
        .configurationdisplayName("My Widget")
        .description("This is an example widget.")
    }
}

如何从我的主应用程序将数据获取到小部件?

解决方法

您可以为小部件和应用程序添加 AppGroup 功能(here是如何添加它的很好的说明)。


UserDefaults

代替

UserDefaults.standard

只需为您的AppGroup使用共享的UserDefaults

UserDefaults(suiteName: <your_app_group>)

然后,您可以按照this answer中的说明读取/写入数据。

文件容器

使用AppGroup授权,您可以访问共享的文件容器:

let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: <your_app_group>)!

并访问如下网址:

let someFileURL = containerURL.appendingPathComponent("SomeFile.txt")

然后,您可以按照此答案中的说明使用共享文件容器:

CoreData

您也可以创建一个共享的CoreData容器:

let storeURL = containerURL.appendingPathComponent("DataModel.sqlite")
let description = NSPersistentStoreDescription(url: storeURL)

let container = NSPersistentContainer(name: "DataModel")
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { ... }

然后,您可以按照此答案中的说明使用共享的CoreData容器:


这是一个GitHub repository,其中包含不同的Widget示例,包括App Group Widget。

,

执行此操作的一种简单方法是将应用和小部件添加到同一个应用组,然后从位于该应用组容器中的 UserDefaults 存储(而不是应用的默认 UserDefaults 存储)中存储和检索数据。 您可以通过使用

初始化 UserDefaults 来访问您的应用程序组的此共享存储
UserDefaults(suiteName: "YOUR_APP_GROUP_NAME")

而不是使用访问它 UserDefaults.standard

This article 更详尽地描述了此过程的细节。