swift – CapacitorJS: is it potential to share native information between iOS widget and Preferences API?

0
77


I’m utilizing a widget in my capacitor app (at present this query solely focuses on iOS).

I need to save an integer from my webview code into Preferences after which be capable to learn it from the iOS widget.

Is that this even potential or am I making an attempt to perform one thing that’s inconceivable? (is it not potential in each iOS AND Android?). I’m particularly skeptic that the write from my webview code is ready to write right into a specifc group, since I’m not certain the Preferences.ConfigureOptions.group referes to the identical idea as a gaggle for iOS app extensions

I created a gaggle for my native app and my native widget in xcode, with the identical identify:
enter image description here

enter image description here

I attempted to do it with configureoptions group however the integer by no means arrives on the widget, it’s non existent:

https://capacitorjs.com/docs/apis/preferences#configureoptions

Right here is my webview code:

const key = 'widgetStreak';
const worth = String(this.streak);
console.log("AAA", key, worth);
await Preferences.configure({group: "group.com.firm.identify"});
await Preferences.set({ key, worth });

Right here is my widget code:

import WidgetKit
import SwiftUI

struct Supplier: TimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), streak: 0)
    }

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), streak: fetchStreak())
        completion(entry)
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []

        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.present.date(byAdding: .hour, worth: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, streak: fetchStreak())
            entries.append(entry)
        }

        let timeline = Timeline(entries: entries, coverage: .atEnd)
        completion(timeline)
    }

    non-public func fetchStreak() -> Int {
        guard let userDefaults = UserDefaults(suiteName: "group.com.firm.identify") else {
            print("Didn't initialize UserDefaults.")
            return 0
        }
        
        // Make sure that UserDefaults are synchronized
        userDefaults.synchronize()
        
        // Test if the important thing exists
        if userDefaults.object(forKey: "widgetStreak") == nil {
            print("Key 'widgetStreak' doesn't exist.")
            return 0
        }
        
        let ret = userDefaults.integer(forKey: "widgetStreak")
        
        if ret == 0 {
            print("The worth for 'widgetStreak' is zero.")
        } else {
            print("The worth for 'widgetStreak' is: (ret)")
        }
        
        return ret
    }

}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let streak: Int
}

struct TestWidgetEntryView : View {
    var entry: Supplier.Entry

    var physique: some View {
        VStack {
            Textual content("Every day Streak")
            Textual content("(entry.streak) days")
                .font(.largeTitle)
        }
    }
}

struct TestWidget: Widget {
    let type: String = "TestWidget"

    var physique: some WidgetConfiguration {
        StaticConfiguration(type: type, supplier: Supplier()) { entry in
            if #accessible(iOS 17.0, *) {
                TestWidgetEntryView(entry: entry)
                    .containerBackground(.fill.tertiary, for: .widget)
            } else {
                TestWidgetEntryView(entry: entry)
                    .padding()
                    .background()
            }
        }
        .configurationDisplayName("Every day Streak Widget")
        .description("Shows your day by day streak.")
    }
}

#Preview(as: .systemSmall) {
    TestWidget()
} timeline: {
    SimpleEntry(date: .now, streak: 0)
    SimpleEntry(date: .now, streak: 5)
}

Right here is the output that I get for my native widget code:

Could not learn values in CFPrefsPlistSource<0x101c854a0> (Area: group.com.felixolszewski.geochamp1, Consumer: kCFPreferencesAnyUser, ByHost: Sure, Container: (null), Contents Want Refresh: Sure): Utilizing kCFPreferencesAnyUser with a container is just allowed for System Containers, detaching from cfprefsd
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.
Key 'widgetStreak' doesn't exist.

Apparently the warning might be ignored:
https://stackoverflow.com/a/39923879/20009330

I additionally tried all of the advices on this publish:
Didn’t learn values in CFPrefsPlistSource iOS 10

However none helped, nonetheless getting the Key 'widgetStreak' doesn't exist., which makes me assume it is simply not potential with Capacitor. Perhaps somebody may recommend some various workarounds? Perhaps the webview localStorage might be accessed from the widget? I discovered some clues to this right here, that localStorage or indexedDB shouldn’t be a great choices, for no matter motive:

https://discussion board.ionicframework.com/t/will-app-clips-be-available-in-ionic/194768/10?u=folsze