diff --git a/SampleWidget/Assets.xcassets/AccentColor.colorset/Contents.json b/SampleWidget/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/SampleWidget/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SampleWidget/Assets.xcassets/AppIcon.appiconset/Contents.json b/SampleWidget/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13613e3 --- /dev/null +++ b/SampleWidget/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SampleWidget/Assets.xcassets/Contents.json b/SampleWidget/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/SampleWidget/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SampleWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json b/SampleWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/SampleWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SampleWidget/Info.plist b/SampleWidget/Info.plist new file mode 100644 index 0000000..0f118fb --- /dev/null +++ b/SampleWidget/Info.plist @@ -0,0 +1,11 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/SampleWidget/SampleWidget.intentdefinition b/SampleWidget/SampleWidget.intentdefinition new file mode 100644 index 0000000..bdb4045 --- /dev/null +++ b/SampleWidget/SampleWidget.intentdefinition @@ -0,0 +1,59 @@ + + + + + INEnums + + INIntentDefinitionModelVersion + 1.2 + INIntentDefinitionNamespace + 88xZPY + INIntentDefinitionSystemVersion + 20A294 + INIntentDefinitionToolsBuildVersion + 12A6144 + INIntentDefinitionToolsVersion + 12.0 + INIntents + + + INIntentCategory + information + INIntentDescriptionID + tVvJ9c + INIntentEligibleForWidgets + + INIntentIneligibleForSuggestions + + INIntentName + Configuration + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + Configuration + INIntentTitleID + gpCwrM + INIntentType + Custom + INIntentVerb + View + + + INTypes + + + diff --git a/SampleWidget/SampleWidget.swift b/SampleWidget/SampleWidget.swift new file mode 100644 index 0000000..77d7cce --- /dev/null +++ b/SampleWidget/SampleWidget.swift @@ -0,0 +1,69 @@ +// +// SampleWidget.swift +// SampleWidget +// +// Created by Asif on 28/01/23. +// Copyright © 2023 SkyDevz. All rights reserved. +// + +import WidgetKit +import SwiftUI +import Intents + +struct Provider: IntentTimelineProvider { + func placeholder(in context: Context) -> SimpleEntry { + SimpleEntry(date: Date(), configuration: ConfigurationIntent()) + } + + func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) { + let entry = SimpleEntry(date: Date(), configuration: configuration) + completion(entry) + } + + func getTimeline(for configuration: ConfigurationIntent, 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)! + let entry = SimpleEntry(date: entryDate, configuration: configuration) + entries.append(entry) + } + + let timeline = Timeline(entries: entries, policy: .atEnd) + completion(timeline) + } +} + +struct SimpleEntry: TimelineEntry { + let date: Date + let configuration: ConfigurationIntent +} + +struct SampleWidgetEntryView : View { + var entry: Provider.Entry + + var body: some View { + Text(entry.date, style: .time) + } +} + +struct SampleWidget: Widget { + let kind: String = "SampleWidget" + + var body: some WidgetConfiguration { + IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in + SampleWidgetEntryView(entry: entry) + } + .configurationDisplayName("My Widget") + .description("This is an example widget.") + } +} + +struct SampleWidget_Previews: PreviewProvider { + static var previews: some View { + SampleWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent())) + .previewContext(WidgetPreviewContext(family: .systemSmall)) + } +} diff --git a/SampleWidget/SampleWidgetBundle.swift b/SampleWidget/SampleWidgetBundle.swift new file mode 100644 index 0000000..ff1bc01 --- /dev/null +++ b/SampleWidget/SampleWidgetBundle.swift @@ -0,0 +1,20 @@ +// +// SampleWidgetBundle.swift +// SampleWidget +// +// Created by Asif on 28/01/23. +// Copyright © 2023 SkyDevz. All rights reserved. +// + +import WidgetKit +import SwiftUI + +@main +struct SampleWidgetBundle: WidgetBundle { + var body: some Widget { + SampleWidget() + if #available(iOS 16.1, *) { + SampleWidgetLiveActivity() + } + } +} diff --git a/SampleWidget/SampleWidgetLiveActivity.swift b/SampleWidget/SampleWidgetLiveActivity.swift new file mode 100644 index 0000000..c71ea43 --- /dev/null +++ b/SampleWidget/SampleWidgetLiveActivity.swift @@ -0,0 +1,59 @@ +// +// SampleWidgetLiveActivity.swift +// SampleWidget +// +// Created by Asif on 28/01/23. +// Copyright © 2023 SkyDevz. All rights reserved. +// + +import ActivityKit +import WidgetKit +import SwiftUI + +struct SampleWidgetAttributes: ActivityAttributes { + public struct ContentState: Codable, Hashable { + // Dynamic stateful properties about your activity go here! + var value: Int + } + + // Fixed non-changing properties about your activity go here! + var name: String +} + +@available(iOSApplicationExtension 16.1, *) +struct SampleWidgetLiveActivity: Widget { + var body: some WidgetConfiguration { + ActivityConfiguration(for: SampleWidgetAttributes.self) { context in + // Lock screen/banner UI goes here + VStack { + Text("Hello") + } + .activityBackgroundTint(Color.cyan) + .activitySystemActionForegroundColor(Color.black) + + } dynamicIsland: { context in + DynamicIsland { + // Expanded UI goes here. Compose the expanded UI through + // various regions, like leading/trailing/center/bottom + DynamicIslandExpandedRegion(.leading) { + Text("Leading") + } + DynamicIslandExpandedRegion(.trailing) { + Text("Trailing") + } + DynamicIslandExpandedRegion(.bottom) { + Text("Bottom") + // more content + } + } compactLeading: { + Text("L") + } compactTrailing: { + Text("T") + } minimal: { + Text("Min") + } + .widgetURL(URL(string: "http://www.apple.com")) + .keylineTint(Color.red) + } + } +} diff --git a/project.yml b/project.yml index e6a8895..425cff9 100644 --- a/project.yml +++ b/project.yml @@ -56,3 +56,10 @@ targets: Release: CODE_SIGN_STYLE: Automatic CODE_SIGN_IDENTITY: "Apple Distribution" + SampleWidget: + type: app-extension + platform: iOS + deploymentTarget: + iOS: 15.0 + sources: + - SampleWidget