From a0c33d345f08f4475c8086468548da7da3139613 Mon Sep 17 00:00:00 2001 From: alieren97 Date: Wed, 6 Sep 2023 09:14:11 +0300 Subject: [PATCH] Created app groups for widget extension and app, Fetching favorite coins from AppStorage added. --- .../CoinWidgetExtension.entitlements | 10 +++ CoinWidgetExtension/CoinWidgetExtension.swift | 77 ++++++++++++++----- .../SampleAppSwiftUI.entitlements | 10 +++ .../Utility/Managers/StorageManager.swift | 4 +- 4 files changed, 81 insertions(+), 20 deletions(-) create mode 100644 CoinWidgetExtension/CoinWidgetExtension.entitlements create mode 100644 SampleAppSwiftUI/SampleAppSwiftUI.entitlements diff --git a/CoinWidgetExtension/CoinWidgetExtension.entitlements b/CoinWidgetExtension/CoinWidgetExtension.entitlements new file mode 100644 index 0000000..0b4100d --- /dev/null +++ b/CoinWidgetExtension/CoinWidgetExtension.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.com.adesso.SampleAppSwiftUI + + + diff --git a/CoinWidgetExtension/CoinWidgetExtension.swift b/CoinWidgetExtension/CoinWidgetExtension.swift index 2d5e8f5..c718b63 100644 --- a/CoinWidgetExtension/CoinWidgetExtension.swift +++ b/CoinWidgetExtension/CoinWidgetExtension.swift @@ -9,40 +9,57 @@ import WidgetKit import SwiftUI struct Provider: TimelineProvider { + @AppStorage("favoriteCoins", store: UserDefaults(suiteName: "group.com.adesso.SampleAppSwiftUI")) var favoriteCoins: [CoinData] = [] + func placeholder(in context: Context) -> SimpleEntry { - SimpleEntry(date: Date()) + SimpleEntry(favoriteCoins: favoriteCoins) } func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { - let entry = SimpleEntry(date: Date()) + let entry = SimpleEntry(favoriteCoins: favoriteCoins) completion(entry) } func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { - var entries: [SimpleEntry] = [] - - // Generate a timeline consisting of five entries an hour apart, starting from the current date. - let currentDate = Date() - for hourOffset in 0 ..< 5 { - let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate) ?? Date() - let entry = SimpleEntry(date: entryDate) - entries.append(entry) - } - - let timeline = Timeline(entries: entries, policy: .atEnd) + let timeline = Timeline(entries: [SimpleEntry(favoriteCoins: favoriteCoins)], policy: .atEnd) completion(timeline) } } struct SimpleEntry: TimelineEntry { - let date: Date + let date = Date() + var favoriteCoins: [CoinData] } -struct CoinWidgetExtensionEntryView : View { +struct CoinWidgetExtensionEntryView: View { + @Environment(\.widgetFamily) var widgetFamily var entry: Provider.Entry + @ViewBuilder + var emptyView: some View { + Text("There are no favorite coins") + } + + @ViewBuilder + var coinsView: some View { + VStack { + ForEach(entry.favoriteCoins) { val in + HStack { + Text(val.coinInfo?.title ?? "") + } + } + } + } + var body: some View { - Text(entry.date, style: .time) + switch widgetFamily { + case .systemSmall: + entry.favoriteCoins.isEmpty ? AnyView(emptyView) : AnyView(coinsView) + case .systemMedium: + entry.favoriteCoins.isEmpty ? AnyView(emptyView) : AnyView(coinsView) + default: + Text(entry.date, style: .time) + } } } @@ -55,13 +72,35 @@ struct CoinWidgetExtension: Widget { } .configurationDisplayName("My Widget") .description("This is an example widget.") + .supportedFamilies([.systemSmall, .systemMedium]) } } struct CoinWidgetExtension_Previews: PreviewProvider { static var previews: some View { - VStack { - CoinWidgetExtensionEntryView(entry: SimpleEntry(date: Date())) - }.previewContext(WidgetPreviewContext(family: .systemSmall)) + + CoinWidgetExtensionEntryView(entry: SimpleEntry(favoriteCoins: [])).previewContext(WidgetPreviewContext(family: .systemSmall)) + CoinWidgetExtensionEntryView(entry: SimpleEntry(favoriteCoins: [])).previewContext(WidgetPreviewContext(family: .systemMedium)) + + } +} + +extension Array: RawRepresentable where Element: Codable { +public init?(rawValue: String) { + guard let data = rawValue.data(using: .utf8), + let result = try? JSONDecoder().decode([Element].self, from: data) + else { + return nil + } + self = result +} + +public var rawValue: String { + guard let data = try? JSONEncoder().encode(self), + let result = String(data: data, encoding: .utf8) + else { + return "[]" + } + return result } } diff --git a/SampleAppSwiftUI/SampleAppSwiftUI.entitlements b/SampleAppSwiftUI/SampleAppSwiftUI.entitlements new file mode 100644 index 0000000..0b4100d --- /dev/null +++ b/SampleAppSwiftUI/SampleAppSwiftUI.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.com.adesso.SampleAppSwiftUI + + + diff --git a/SampleAppSwiftUI/Utility/Managers/StorageManager.swift b/SampleAppSwiftUI/Utility/Managers/StorageManager.swift index f5695d2..8c4f347 100644 --- a/SampleAppSwiftUI/Utility/Managers/StorageManager.swift +++ b/SampleAppSwiftUI/Utility/Managers/StorageManager.swift @@ -6,14 +6,16 @@ // import SwiftUI +import WidgetKit final class StorageManager: ObservableObject { static let shared = StorageManager() - @AppStorage("favoriteCoins") var favoriteCoins: [CoinData] = [] { + @AppStorage("favoriteCoins", store: UserDefaults(suiteName: "group.com.adesso.SampleAppSwiftUI")) var favoriteCoins: [CoinData] = [] { didSet { objectWillChange.send() + WidgetCenter.shared.reloadAllTimelines() } }