End of Step 10: Widget code moved to a shared folder.

xcode15-and-vision
Alan Francis 2 years ago
parent ed27943a65
commit 42580684c1
  1. 24
      JustOneThing.xcodeproj/project.pbxproj
  2. 69
      MacWidget/MacWidget.swift
  3. 68
      PhoneWidget/PhoneWidget.swift
  4. 16
      PhoneWidget/PhoneWidgetBundle.swift
  5. 27
      WidgetShared/JustOneThingWidget.swift

@ -16,24 +16,23 @@
547201902A36563C005B2FCC /* Widget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 54928C1C2A35F89900095445 /* Widget.intentdefinition */; };
547201912A36563C005B2FCC /* WidgetAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 54928C372A35F8B800095445 /* WidgetAssets.xcassets */; };
547201932A365868005B2FCC /* Widget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 54928C1C2A35F89900095445 /* Widget.intentdefinition */; };
547201962A461DBE005B2FCC /* JustOneThingWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C4A2A35F8CB00095445 /* JustOneThingWidget.swift */; };
547201972A461DBE005B2FCC /* JustOneThingWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C4A2A35F8CB00095445 /* JustOneThingWidget.swift */; };
5483903B2A2A773900BF5624 /* JustOneThingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5483903A2A2A773900BF5624 /* JustOneThingApp.swift */; };
5483903D2A2A773900BF5624 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5483903C2A2A773900BF5624 /* ContentView.swift */; };
5483903F2A2A773A00BF5624 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5483903E2A2A773A00BF5624 /* Assets.xcassets */; };
54928C162A35F89900095445 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54928C152A35F89900095445 /* WidgetKit.framework */; };
54928C182A35F89900095445 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54928C172A35F89900095445 /* SwiftUI.framework */; };
54928C1B2A35F89900095445 /* MacWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C1A2A35F89900095445 /* MacWidget.swift */; };
54928C212A35F89A00095445 /* Widget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 54928C1C2A35F89900095445 /* Widget.intentdefinition */; };
54928C222A35F89A00095445 /* Widget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 54928C1C2A35F89900095445 /* Widget.intentdefinition */; };
54928C252A35F89A00095445 /* MacWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 54928C132A35F89900095445 /* MacWidgetExtension.appex */; platformFilters = (macos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
54928C2F2A35F8B800095445 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54928C152A35F89900095445 /* WidgetKit.framework */; };
54928C302A35F8B800095445 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54928C172A35F89900095445 /* SwiftUI.framework */; };
54928C332A35F8B800095445 /* PhoneWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C322A35F8B800095445 /* PhoneWidgetBundle.swift */; };
54928C352A35F8B800095445 /* PhoneWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C342A35F8B800095445 /* PhoneWidget.swift */; };
54928C382A35F8B800095445 /* WidgetAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 54928C372A35F8B800095445 /* WidgetAssets.xcassets */; };
54928C3E2A35F8B800095445 /* PhoneWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 54928C2E2A35F8B800095445 /* PhoneWidgetExtension.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
54928C472A35F8CB00095445 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54928C152A35F89900095445 /* WidgetKit.framework */; };
54928C482A35F8CB00095445 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54928C172A35F89900095445 /* SwiftUI.framework */; };
54928C4B2A35F8CB00095445 /* WatchWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C4A2A35F8CB00095445 /* WatchWidget.swift */; };
54928C4B2A35F8CB00095445 /* JustOneThingWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C4A2A35F8CB00095445 /* JustOneThingWidget.swift */; };
54928C542A35F8CC00095445 /* WatchWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 54928C462A35F8CB00095445 /* WatchWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
@ -118,16 +117,13 @@
54928C132A35F89900095445 /* MacWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MacWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
54928C152A35F89900095445 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
54928C172A35F89900095445 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
54928C1A2A35F89900095445 /* MacWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacWidget.swift; sourceTree = "<group>"; };
54928C1C2A35F89900095445 /* Widget.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = Widget.intentdefinition; sourceTree = "<group>"; };
54928C202A35F89A00095445 /* MacWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MacWidget.entitlements; sourceTree = "<group>"; };
54928C2E2A35F8B800095445 /* PhoneWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PhoneWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
54928C322A35F8B800095445 /* PhoneWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneWidgetBundle.swift; sourceTree = "<group>"; };
54928C342A35F8B800095445 /* PhoneWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneWidget.swift; sourceTree = "<group>"; };
54928C372A35F8B800095445 /* WidgetAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = WidgetAssets.xcassets; sourceTree = "<group>"; };
54928C392A35F8B800095445 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
54928C462A35F8CB00095445 /* WatchWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WatchWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
54928C4A2A35F8CB00095445 /* WatchWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchWidget.swift; sourceTree = "<group>"; };
54928C4A2A35F8CB00095445 /* JustOneThingWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JustOneThingWidget.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -199,6 +195,7 @@
54928C372A35F8B800095445 /* WidgetAssets.xcassets */,
54928C392A35F8B800095445 /* Info.plist */,
54928C1C2A35F89900095445 /* Widget.intentdefinition */,
54928C4A2A35F8CB00095445 /* JustOneThingWidget.swift */,
);
path = WidgetShared;
sourceTree = "<group>";
@ -251,7 +248,6 @@
isa = PBXGroup;
children = (
54928C202A35F89A00095445 /* MacWidget.entitlements */,
54928C1A2A35F89900095445 /* MacWidget.swift */,
);
path = MacWidget;
sourceTree = "<group>";
@ -260,8 +256,6 @@
isa = PBXGroup;
children = (
547201942A461554005B2FCC /* PhoneWidget.entitlements */,
54928C322A35F8B800095445 /* PhoneWidgetBundle.swift */,
54928C342A35F8B800095445 /* PhoneWidget.swift */,
);
path = PhoneWidget;
sourceTree = "<group>";
@ -270,7 +264,6 @@
isa = PBXGroup;
children = (
547201952A461558005B2FCC /* WatchWidget.entitlements */,
54928C4A2A35F8CB00095445 /* WatchWidget.swift */,
);
path = WatchWidget;
sourceTree = "<group>";
@ -488,7 +481,7 @@
buildActionMask = 2147483647;
files = (
54928C212A35F89A00095445 /* Widget.intentdefinition in Sources */,
54928C1B2A35F89900095445 /* MacWidget.swift in Sources */,
547201972A461DBE005B2FCC /* JustOneThingWidget.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -496,8 +489,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
54928C352A35F8B800095445 /* PhoneWidget.swift in Sources */,
54928C332A35F8B800095445 /* PhoneWidgetBundle.swift in Sources */,
547201962A461DBE005B2FCC /* JustOneThingWidget.swift in Sources */,
5472018E2A36563B005B2FCC /* Widget.intentdefinition in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -507,7 +499,7 @@
buildActionMask = 2147483647;
files = (
547201902A36563C005B2FCC /* Widget.intentdefinition in Sources */,
54928C4B2A35F8CB00095445 /* WatchWidget.swift in Sources */,
54928C4B2A35F8CB00095445 /* JustOneThingWidget.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -1,69 +0,0 @@
//
// MacWidget.swift
// MacWidget
//
// Created by Alan Francis on 11/06/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<Entry>) -> ()) {
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 MacWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
Text(entry.date, style: .time)
}
}
@main
struct MacWidget: Widget {
let kind: String = "MacWidget"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
MacWidgetEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
struct MacWidget_Previews: PreviewProvider {
static var previews: some View {
MacWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent()))
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}

@ -1,68 +0,0 @@
//
// PhoneWidget.swift
// PhoneWidget
//
// Created by Alan Francis on 11/06/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<Entry>) -> ()) {
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 PhoneWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
Text(entry.date, style: .time)
}
}
struct PhoneWidget: Widget {
let kind: String = "PhoneWidget"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
PhoneWidgetEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
struct PhoneWidget_Previews: PreviewProvider {
static var previews: some View {
PhoneWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent()))
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}

@ -1,16 +0,0 @@
//
// PhoneWidgetBundle.swift
// PhoneWidget
//
// Created by Alan Francis on 11/06/2023.
//
import WidgetKit
import SwiftUI
@main
struct PhoneWidgetBundle: WidgetBundle {
var body: some Widget {
PhoneWidget()
}
}

@ -1,6 +1,6 @@
//
// WatchWidget.swift
// WatchWidget
// JustOneThingWidget.swift
// JustOneThing
//
// Created by Alan Francis on 11/06/2023.
//
@ -9,6 +9,13 @@ import WidgetKit
import SwiftUI
import Intents
@main
struct JustOneThingWidgetBundle: WidgetBundle {
var body: some Widget {
JustOneThingWidget()
}
}
struct Provider: IntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationIntent())
@ -46,7 +53,7 @@ struct SimpleEntry: TimelineEntry {
let configuration: ConfigurationIntent
}
struct WatchWidgetEntryView : View {
struct JustOneThingWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
@ -54,22 +61,14 @@ struct WatchWidgetEntryView : View {
}
}
@main
struct WatchWidget: Widget {
let kind: String = "WatchWidget"
struct JustOneThingWidget: Widget {
let kind: String = "JustOneThingWidget"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
WatchWidgetEntryView(entry: entry)
JustOneThingWidgetEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
struct WatchWidget_Previews: PreviewProvider {
static var previews: some View {
WatchWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent()))
.previewContext(WidgetPreviewContext(family: .accessoryRectangular))
}
}
Loading…
Cancel
Save