diff --git a/LaunchWidget/Assets.xcassets/AccentColor.colorset/Contents.json b/LaunchWidget/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/LaunchWidget/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/LaunchWidget/Assets.xcassets/AppIcon.appiconset/Contents.json b/LaunchWidget/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..13613e3
--- /dev/null
+++ b/LaunchWidget/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/LaunchWidget/Assets.xcassets/Contents.json b/LaunchWidget/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/LaunchWidget/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/LaunchWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json b/LaunchWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/LaunchWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/LaunchWidget/Info.plist b/LaunchWidget/Info.plist
new file mode 100644
index 0000000..0f118fb
--- /dev/null
+++ b/LaunchWidget/Info.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ NSExtension
+
+ NSExtensionPointIdentifier
+ com.apple.widgetkit-extension
+
+
+
diff --git a/LaunchWidget/LaunchWidget.intentdefinition b/LaunchWidget/LaunchWidget.intentdefinition
new file mode 100644
index 0000000..bdb4045
--- /dev/null
+++ b/LaunchWidget/LaunchWidget.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/LaunchWidget/LaunchWidget.swift b/LaunchWidget/LaunchWidget.swift
new file mode 100644
index 0000000..fab3040
--- /dev/null
+++ b/LaunchWidget/LaunchWidget.swift
@@ -0,0 +1,68 @@
+//
+// LaunchWidget.swift
+// LaunchWidget
+//
+// Created by Laurent Morvillier on 25/01/2023.
+//
+
+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 LaunchWidgetEntryView : View {
+ var entry: Provider.Entry
+
+ var body: some View {
+ Text(entry.date, style: .time)
+ }
+}
+
+struct LaunchWidget: Widget {
+ let kind: String = "LaunchWidget"
+
+ var body: some WidgetConfiguration {
+ IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
+ LaunchWidgetEntryView(entry: entry)
+ }
+ .configurationDisplayName("My Widget")
+ .description("This is an example widget.")
+ }
+}
+
+struct LaunchWidget_Previews: PreviewProvider {
+ static var previews: some View {
+ LaunchWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent()))
+ .previewContext(WidgetPreviewContext(family: .systemSmall))
+ }
+}
diff --git a/LaunchWidget/LaunchWidgetBundle.swift b/LaunchWidget/LaunchWidgetBundle.swift
new file mode 100644
index 0000000..5fd57e3
--- /dev/null
+++ b/LaunchWidget/LaunchWidgetBundle.swift
@@ -0,0 +1,17 @@
+//
+// LaunchWidgetBundle.swift
+// LaunchWidget
+//
+// Created by Laurent Morvillier on 25/01/2023.
+//
+
+import WidgetKit
+import SwiftUI
+
+@main
+struct LaunchWidgetBundle: WidgetBundle {
+ var body: some Widget {
+ LaunchWidget()
+ LaunchWidgetLiveActivity()
+ }
+}
diff --git a/LaunchWidget/LaunchWidgetLiveActivity.swift b/LaunchWidget/LaunchWidgetLiveActivity.swift
new file mode 100644
index 0000000..dc85417
--- /dev/null
+++ b/LaunchWidget/LaunchWidgetLiveActivity.swift
@@ -0,0 +1,77 @@
+//
+// LaunchWidgetLiveActivity.swift
+// LaunchWidget
+//
+// Created by Laurent Morvillier on 25/01/2023.
+//
+
+import ActivityKit
+import WidgetKit
+import SwiftUI
+
+struct LaunchWidgetAttributes: 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
+}
+
+struct LaunchWidgetLiveActivity: Widget {
+ var body: some WidgetConfiguration {
+ ActivityConfiguration(for: LaunchWidgetAttributes.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)
+ }
+ }
+}
+
+struct LaunchWidgetLiveActivity_Previews: PreviewProvider {
+ static let attributes = LaunchWidgetAttributes(name: "Me")
+ static let contentState = LaunchWidgetAttributes.ContentState(value: 3)
+
+ static var previews: some View {
+ attributes
+ .previewContext(contentState, viewKind: .dynamicIsland(.compact))
+ .previewDisplayName("Island Compact")
+ attributes
+ .previewContext(contentState, viewKind: .dynamicIsland(.expanded))
+ .previewDisplayName("Island Expanded")
+ attributes
+ .previewContext(contentState, viewKind: .dynamicIsland(.minimal))
+ .previewDisplayName("Minimal")
+ attributes
+ .previewContext(contentState, viewKind: .content)
+ .previewDisplayName("Notification")
+ }
+}
diff --git a/LeCountdown.xcodeproj/project.pbxproj b/LeCountdown.xcodeproj/project.pbxproj
index 2bc76f8..578700d 100644
--- a/LeCountdown.xcodeproj/project.pbxproj
+++ b/LeCountdown.xcodeproj/project.pbxproj
@@ -21,6 +21,15 @@
C438C7C12980228B00BF3EF9 /* CountdownScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7C02980228B00BF3EF9 /* CountdownScheduler.swift */; };
C438C7C5298024E900BF3EF9 /* NSManagedContext+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7C4298024E900BF3EF9 /* NSManagedContext+Extensions.swift */; };
C438C7C929803CA000BF3EF9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7C829803CA000BF3EF9 /* AppDelegate.swift */; };
+ C438C7D12981216200BF3EF9 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C438C7D02981216200BF3EF9 /* WidgetKit.framework */; };
+ C438C7D32981216200BF3EF9 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C438C7D22981216200BF3EF9 /* SwiftUI.framework */; };
+ C438C7D62981216200BF3EF9 /* LaunchWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7D52981216200BF3EF9 /* LaunchWidgetBundle.swift */; };
+ C438C7D82981216200BF3EF9 /* LaunchWidgetLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7D72981216200BF3EF9 /* LaunchWidgetLiveActivity.swift */; };
+ C438C7DA2981216200BF3EF9 /* LaunchWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7D92981216200BF3EF9 /* LaunchWidget.swift */; };
+ C438C7DD2981216300BF3EF9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C438C7DC2981216300BF3EF9 /* Assets.xcassets */; };
+ C438C7DF2981216300BF3EF9 /* LaunchWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = C438C7DB2981216200BF3EF9 /* LaunchWidget.intentdefinition */; };
+ C438C7E02981216300BF3EF9 /* LaunchWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = C438C7DB2981216200BF3EF9 /* LaunchWidget.intentdefinition */; };
+ C438C7E32981216300BF3EF9 /* LaunchWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C438C7CE2981216200BF3EF9 /* LaunchWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -38,8 +47,29 @@
remoteGlobalIDString = C4060DBB297AE73B003FAB80;
remoteInfo = LeCountdown;
};
+ C438C7E12981216300BF3EF9 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C4060DB4297AE73B003FAB80 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C438C7CD2981216200BF3EF9;
+ remoteInfo = LaunchWidgetExtension;
+ };
/* End PBXContainerItemProxy section */
+/* Begin PBXCopyFilesBuildPhase section */
+ C438C7E72981216300BF3EF9 /* Embed Foundation Extensions */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 13;
+ files = (
+ C438C7E32981216300BF3EF9 /* LaunchWidgetExtension.appex in Embed Foundation Extensions */,
+ );
+ name = "Embed Foundation Extensions";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
/* Begin PBXFileReference section */
C4060DBC297AE73B003FAB80 /* LeCountdown.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LeCountdown.app; sourceTree = BUILT_PRODUCTS_DIR; };
C4060DBF297AE73B003FAB80 /* LeCountdownApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeCountdownApp.swift; sourceTree = ""; };
@@ -59,6 +89,15 @@
C438C7C02980228B00BF3EF9 /* CountdownScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountdownScheduler.swift; sourceTree = ""; };
C438C7C4298024E900BF3EF9 /* NSManagedContext+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedContext+Extensions.swift"; sourceTree = ""; };
C438C7C829803CA000BF3EF9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ C438C7CE2981216200BF3EF9 /* LaunchWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = LaunchWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
+ C438C7D02981216200BF3EF9 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
+ C438C7D22981216200BF3EF9 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
+ C438C7D52981216200BF3EF9 /* LaunchWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchWidgetBundle.swift; sourceTree = ""; };
+ C438C7D72981216200BF3EF9 /* LaunchWidgetLiveActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchWidgetLiveActivity.swift; sourceTree = ""; };
+ C438C7D92981216200BF3EF9 /* LaunchWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchWidget.swift; sourceTree = ""; };
+ C438C7DB2981216200BF3EF9 /* LaunchWidget.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = LaunchWidget.intentdefinition; sourceTree = ""; };
+ C438C7DC2981216300BF3EF9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ C438C7DE2981216300BF3EF9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -83,6 +122,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ C438C7CB2981216200BF3EF9 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C438C7D32981216200BF3EF9 /* SwiftUI.framework in Frameworks */,
+ C438C7D12981216200BF3EF9 /* WidgetKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -92,6 +140,8 @@
C4060DBE297AE73B003FAB80 /* LeCountdown */,
C4060DD5297AE73D003FAB80 /* LeCountdownTests */,
C4060DDF297AE73D003FAB80 /* LeCountdownUITests */,
+ C438C7D42981216200BF3EF9 /* LaunchWidget */,
+ C438C7CF2981216200BF3EF9 /* Frameworks */,
C4060DBD297AE73B003FAB80 /* Products */,
);
sourceTree = "";
@@ -102,6 +152,7 @@
C4060DBC297AE73B003FAB80 /* LeCountdown.app */,
C4060DD2297AE73D003FAB80 /* LeCountdownTests.xctest */,
C4060DDC297AE73D003FAB80 /* LeCountdownUITests.xctest */,
+ C438C7CE2981216200BF3EF9 /* LaunchWidgetExtension.appex */,
);
name = Products;
sourceTree = "";
@@ -150,6 +201,28 @@
path = LeCountdownUITests;
sourceTree = "";
};
+ C438C7CF2981216200BF3EF9 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ C438C7D02981216200BF3EF9 /* WidgetKit.framework */,
+ C438C7D22981216200BF3EF9 /* SwiftUI.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ C438C7D42981216200BF3EF9 /* LaunchWidget */ = {
+ isa = PBXGroup;
+ children = (
+ C438C7D52981216200BF3EF9 /* LaunchWidgetBundle.swift */,
+ C438C7D72981216200BF3EF9 /* LaunchWidgetLiveActivity.swift */,
+ C438C7D92981216200BF3EF9 /* LaunchWidget.swift */,
+ C438C7DB2981216200BF3EF9 /* LaunchWidget.intentdefinition */,
+ C438C7DC2981216300BF3EF9 /* Assets.xcassets */,
+ C438C7DE2981216300BF3EF9 /* Info.plist */,
+ );
+ path = LaunchWidget;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -160,10 +233,12 @@
C4060DB8297AE73B003FAB80 /* Sources */,
C4060DB9297AE73B003FAB80 /* Frameworks */,
C4060DBA297AE73B003FAB80 /* Resources */,
+ C438C7E72981216300BF3EF9 /* Embed Foundation Extensions */,
);
buildRules = (
);
dependencies = (
+ C438C7E22981216300BF3EF9 /* PBXTargetDependency */,
);
name = LeCountdown;
productName = LeCountdown;
@@ -206,6 +281,23 @@
productReference = C4060DDC297AE73D003FAB80 /* LeCountdownUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
+ C438C7CD2981216200BF3EF9 /* LaunchWidgetExtension */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C438C7E42981216300BF3EF9 /* Build configuration list for PBXNativeTarget "LaunchWidgetExtension" */;
+ buildPhases = (
+ C438C7CA2981216200BF3EF9 /* Sources */,
+ C438C7CB2981216200BF3EF9 /* Frameworks */,
+ C438C7CC2981216200BF3EF9 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = LaunchWidgetExtension;
+ productName = LaunchWidgetExtension;
+ productReference = C438C7CE2981216200BF3EF9 /* LaunchWidgetExtension.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -227,6 +319,9 @@
CreatedOnToolsVersion = 14.2;
TestTargetID = C4060DBB297AE73B003FAB80;
};
+ C438C7CD2981216200BF3EF9 = {
+ CreatedOnToolsVersion = 14.2;
+ };
};
};
buildConfigurationList = C4060DB7297AE73B003FAB80 /* Build configuration list for PBXProject "LeCountdown" */;
@@ -245,6 +340,7 @@
C4060DBB297AE73B003FAB80 /* LeCountdown */,
C4060DD1297AE73D003FAB80 /* LeCountdownTests */,
C4060DDB297AE73D003FAB80 /* LeCountdownUITests */,
+ C438C7CD2981216200BF3EF9 /* LaunchWidgetExtension */,
);
};
/* End PBXProject section */
@@ -273,6 +369,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ C438C7CC2981216200BF3EF9 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C438C7DD2981216300BF3EF9 /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -289,6 +393,7 @@
C4060DCC297AE73D003FAB80 /* LeCountdown.xcdatamodeld in Sources */,
C438C7C5298024E900BF3EF9 /* NSManagedContext+Extensions.swift in Sources */,
C4060DC0297AE73B003FAB80 /* LeCountdownApp.swift in Sources */,
+ C438C7E02981216300BF3EF9 /* LaunchWidget.intentdefinition in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -309,6 +414,17 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ C438C7CA2981216200BF3EF9 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C438C7D62981216200BF3EF9 /* LaunchWidgetBundle.swift in Sources */,
+ C438C7DF2981216300BF3EF9 /* LaunchWidget.intentdefinition in Sources */,
+ C438C7D82981216200BF3EF9 /* LaunchWidgetLiveActivity.swift in Sources */,
+ C438C7DA2981216200BF3EF9 /* LaunchWidget.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -322,6 +438,11 @@
target = C4060DBB297AE73B003FAB80 /* LeCountdown */;
targetProxy = C4060DDD297AE73D003FAB80 /* PBXContainerItemProxy */;
};
+ C438C7E22981216300BF3EF9 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C438C7CD2981216200BF3EF9 /* LaunchWidgetExtension */;
+ targetProxy = C438C7E12981216300BF3EF9 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -442,6 +563,7 @@
C4060DE7297AE73D003FAB80 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
@@ -471,6 +593,7 @@
C4060DE8297AE73D003FAB80 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
@@ -573,6 +696,60 @@
};
name = Release;
};
+ C438C7E52981216300BF3EF9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = 526E96RFNP;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = LaunchWidget/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = LaunchWidget;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown.LaunchWidget;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ C438C7E62981216300BF3EF9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = 526E96RFNP;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = LaunchWidget/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = LaunchWidget;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown.LaunchWidget;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -612,6 +789,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ C438C7E42981216300BF3EF9 /* Build configuration list for PBXNativeTarget "LaunchWidgetExtension" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C438C7E52981216300BF3EF9 /* Debug */,
+ C438C7E62981216300BF3EF9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
diff --git a/LeCountdown/ContentView.swift b/LeCountdown/ContentView.swift
index 0dbca6f..68b4b05 100644
--- a/LeCountdown/ContentView.swift
+++ b/LeCountdown/ContentView.swift
@@ -43,12 +43,16 @@ struct ContentView: View {
Button {
self._launchCountdown(countdown)
} label: {
- Text(countdown.duration.minuteSecond)
- .aspectRatio(contentMode: .fill)
- .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
- .aspectRatio(1, contentMode: .fit)
- .background(Color(red: 0.9, green: 0.95, blue: 1.0))
- .cornerRadius(40.0)
+ VStack {
+ Text(countdown.name ?? "")
+ Text(countdown.duration.minuteSecond)
+ }
+ .font(.title2)
+ .aspectRatio(contentMode: .fill)
+ .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
+ .aspectRatio(1, contentMode: .fit)
+ .background(Color(red: 0.9, green: 0.95, blue: 1.0))
+ .cornerRadius(40.0)
}
NavigationLink {
diff --git a/LeCountdown/LeCountdown.xcdatamodeld/LeCountdown.xcdatamodel/contents b/LeCountdown/LeCountdown.xcdatamodeld/LeCountdown.xcdatamodel/contents
index 164f4c2..0523d7f 100644
--- a/LeCountdown/LeCountdown.xcdatamodeld/LeCountdown.xcdatamodel/contents
+++ b/LeCountdown/LeCountdown.xcdatamodeld/LeCountdown.xcdatamodel/contents
@@ -3,10 +3,8 @@
+
-
-
-
\ No newline at end of file
diff --git a/LeCountdown/NewCountdownView.swift b/LeCountdown/NewCountdownView.swift
index e6d1d10..5c1eaa5 100644
--- a/LeCountdown/NewCountdownView.swift
+++ b/LeCountdown/NewCountdownView.swift
@@ -32,6 +32,7 @@ struct CountdownEditView : View {
@State var secondsString: String = ""
@State var minutesString: String = ""
+ @State var nameString: String = ""
@State var deleteConfirmationShown: Bool = false
@@ -55,6 +56,11 @@ struct CountdownEditView : View {
.keyboardType(.numberPad)
.focused($textFieldIsFocused)
}
+ Section(header: Text("Name for tracking the activity")) {
+ TextField("name", text: $nameString)
+ .focused($textFieldIsFocused)
+ }
+
Section(header: Text("Properties")) {
Text("Image")
Text("Sound")
@@ -120,6 +126,11 @@ struct CountdownEditView : View {
if seconds > 0 {
self.secondsString = self._numberFormatter.string(from: NSNumber(value: seconds)) ?? ""
}
+
+ if let name = self.countdown.name, !name.isEmpty {
+ self.nameString = name
+ }
+
}
fileprivate let _numberFormatter = NumberFormatter()
@@ -145,6 +156,9 @@ struct CountdownEditView : View {
if temporary {
countdown.order = Int16(self.countdowns.count)
}
+ if !self.nameString.isEmpty {
+ countdown.name = self.nameString
+ }
self._saveContext()
diff --git a/LeCountdown/Persistence.swift b/LeCountdown/Persistence.swift
index b0f7245..82214d6 100644
--- a/LeCountdown/Persistence.swift
+++ b/LeCountdown/Persistence.swift
@@ -15,8 +15,9 @@ struct PersistenceController {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
for i in 0..<3 {
- let newItem = Countdown(context: viewContext)
- newItem.order = Int16(i)
+ let countdown = Countdown(context: viewContext)
+ countdown.order = Int16(i)
+ countdown.name = "Tea"
}
do {
try viewContext.save()