Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share data between main App and Widget in SwiftUI for iOS 14

@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.")
    }
}

How can I get data from my Main App to the widget?

like image 760
codingManMAx Avatar asked Sep 16 '20 14:09

codingManMAx


People also ask

Can you share data from a widget?

The simplest way to send data from a widget to another is by its constructor. Let's say, for example, we need to pass an instance of the above Data class from a screen (PageOne) to another (PageTwo). If you change the data on this page, the updated data is sent to the second page.

How often do iOS widgets update?

For a widget the user frequently views, a daily budget typically includes from 40 to 70 refreshes. This rate roughly translates to widget reloads every 15 to 60 minutes, but it's common for these intervals to vary due to the many factors involved. The system takes a few days to learn the user's behavior.


Video Answer


2 Answers

You can add the AppGroup capability for both your Widget and App (here is a very good explanation how to add it).


UserDefaults

Instead of

UserDefaults.standard

just use the shared UserDefaults for your AppGroup:

UserDefaults(suiteName: <your_app_group>)

Then you can read/write data like explained in this answer.

File Container

With the AppGroup entitlement you get access to the shared File Container:

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

and access an url like this:

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

Then you can use your shared File Container like explained in this answer:

  • How to read files created by the app by iOS WidgetKit?

CoreData

You can create a shared CoreData container as well:

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

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

Then you can use your shared CoreData Container like explained in this answer:

  • Fetch data from CoreData for iOS 14 widget

Here is a GitHub repository with different Widget examples including the App Group Widget.

like image 153
pawello2222 Avatar answered Oct 25 '22 13:10

pawello2222


One simple way to do this is by adding both the app and the widget to the same App Group, and then storing and retrieving data from UserDefaults storage located in that App Group's container instead of the default UserDefaults storage for the app. You can access this shared storage for your App Group by initializing UserDefaults using

UserDefaults(suiteName: "YOUR_APP_GROUP_NAME")

instead of accessing it using UserDefaults.standard.

This article gives a more thorough description of the details of this process.

like image 26
smapi_guru Avatar answered Oct 25 '22 14:10

smapi_guru