Apr 28, 2024 iOS

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


To share data between the main app and a widget in SwiftUI for iOS 14, you can use App Groups and UserDefaults to store and retrieve shared data. Here’s a step-by-step guide on how to do it:

1. Enable App Groups:

First, you need to enable App Groups for both your main app and widget extension. This allows them to share data. You can do this in your Apple Developer account under “Certificates, Identifiers & Profiles” > “App Groups”. Add a new App Group and enable it for both your main app and widget extension.

2. Update App Capabilities:

In Xcode, select your main app target and go to the “Signing & Capabilities” tab. Click the “+” button and add the App Group capability. Do the same for your widget extension target.

3. Set Up Shared UserDefaults:

Create a shared UserDefaults suite that both your main app and widget extension can access. You can do this in your app delegate or scene delegate:

let sharedUserDefaults = UserDefaults(suiteName: "group.yourapp.shared")

4. Write and Read Data:

In your main app, write data to the shared UserDefaults:

sharedUserDefaults.set("Shared data", forKey: "sharedKey")

In your widget extension, read data from the shared UserDefaults:

if let sharedData = sharedUserDefaults.string(forKey: "sharedKey") {
    // Use sharedData in your widget
}

Example:

Here’s a simple example demonstrating how to share data between the main app and a widget using UserDefaults:

import SwiftUI
import WidgetKit

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Main App")
            Button("Set Shared Data") {
                let sharedUserDefaults = UserDefaults(suiteName: "group.yourapp.shared")
                sharedUserDefaults?.set("Shared data from main app", forKey: "sharedKey")
                WidgetCenter.shared.reloadAllTimelines()
            }
        }
    }
}

struct MyWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: "MyWidget") { _ in
            WidgetView()
        }
        .configurationDisplayName("My Widget")
        .supportedFamilies([.systemSmall])
    }
}

struct WidgetView: View {
    var body: some View {
        let sharedUserDefaults = UserDefaults(suiteName: "group.yourapp.shared")
        if let sharedData = sharedUserDefaults?.string(forKey: "sharedKey") {
            Text(sharedData)
        } else {
            Text("No shared data")
        }
    }
}

This example demonstrates how to set shared data from the main app and display it in a widget. Remember to replace "group.yourapp.shared" with your actual App Group identifier.

Index