Compare commits

...

4 Commits

  1. 1
      AppShared/JustOneThingApp.swift
  2. 123
      JustOneThing.xcodeproj/project.pbxproj
  3. 10
      JustOneThing/Info.plist
  4. 14
      JustOneThing/JustOneThing.entitlements
  5. 12
      JustOneThingWatch/Info.plist
  6. 14
      JustOneThingWatch/JustOneThingWatch.entitlements
  7. 14
      MacWidget/MacWidget.entitlements
  8. 8
      Model/JustOneThingCloudModel.xcdatamodeld/JustOneThingCloudModel.xcdatamodel/contents
  9. 87
      Model/PersistenceController.swift
  10. 14
      PhoneWidget/PhoneWidget.entitlements
  11. 14
      WatchWidget/WatchWidget.entitlements
  12. 40
      WidgetShared/AccessoryWidget.swift
  13. 63
      WidgetShared/JustOneThingWidget.swift
  14. 26
      WidgetShared/SystemWidget.swift
  15. 21
      WidgetShared/ThingView.swift
  16. 22
      WidgetShared/WidgetBundle.swift

@ -9,6 +9,7 @@ import SwiftUI
@main
struct JustOneThingApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()

@ -19,8 +19,8 @@
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 */; };
547201962A461DBE005B2FCC /* SystemWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C4A2A35F8CB00095445 /* SystemWidget.swift */; };
547201972A461DBE005B2FCC /* SystemWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54928C4A2A35F8CB00095445 /* SystemWidget.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 */; };
@ -35,11 +35,28 @@
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 /* 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, ); }; };
5493A81B2A471E37001EBA08 /* JustOneThingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5493A81A2A471E36001EBA08 /* JustOneThingProvider.swift */; };
5493A81C2A471E37001EBA08 /* JustOneThingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5493A81A2A471E36001EBA08 /* JustOneThingProvider.swift */; };
5493A81D2A471E37001EBA08 /* JustOneThingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5493A81A2A471E36001EBA08 /* JustOneThingProvider.swift */; };
54AE28412A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 54AE283F2A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld */; };
54AE28422A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 54AE283F2A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld */; };
54AE28432A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 54AE283F2A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld */; };
54AE28442A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 54AE283F2A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld */; };
54AE28452A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 54AE283F2A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld */; };
54AE28472A58245700719A56 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54AE28462A58245700719A56 /* PersistenceController.swift */; };
54AE28482A58245700719A56 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54AE28462A58245700719A56 /* PersistenceController.swift */; };
54AE28492A58245700719A56 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54AE28462A58245700719A56 /* PersistenceController.swift */; };
54AE284A2A58245700719A56 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54AE28462A58245700719A56 /* PersistenceController.swift */; };
54AE284B2A58245700719A56 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54AE28462A58245700719A56 /* PersistenceController.swift */; };
54BD36092A5700480022D6BE /* ThingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD36082A5700480022D6BE /* ThingView.swift */; };
54BD360A2A5700480022D6BE /* ThingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD36082A5700480022D6BE /* ThingView.swift */; };
54BD360B2A5700480022D6BE /* ThingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD36082A5700480022D6BE /* ThingView.swift */; };
54BD360D2A57020E0022D6BE /* WidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD360C2A57020E0022D6BE /* WidgetBundle.swift */; };
54BD360E2A57020E0022D6BE /* WidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD360C2A57020E0022D6BE /* WidgetBundle.swift */; };
54BD360F2A57020E0022D6BE /* WidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD360C2A57020E0022D6BE /* WidgetBundle.swift */; };
54BD36122A57021E0022D6BE /* AccessoryWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD36102A57021E0022D6BE /* AccessoryWidget.swift */; };
54BD36132A57021E0022D6BE /* AccessoryWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BD36102A57021E0022D6BE /* AccessoryWidget.swift */; };
54EB3C1F2A5434A30082B059 /* Thing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54EB3C1E2A5434A30082B059 /* Thing.swift */; };
54EB3C202A5434A30082B059 /* Thing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54EB3C1E2A5434A30082B059 /* Thing.swift */; };
54EB3C212A5434A30082B059 /* Thing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54EB3C1E2A5434A30082B059 /* Thing.swift */; };
@ -117,6 +134,8 @@
5407E5062A35B96E00EF00B8 /* JustOneThingWatch.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = JustOneThingWatch.entitlements; sourceTree = "<group>"; };
5416C7372A56A867002196EE /* InterfaceExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceExtensions.swift; sourceTree = "<group>"; };
5431ED6D2A2A77C900515680 /* JustOneThingWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JustOneThingWatch.app; sourceTree = BUILT_PRODUCTS_DIR; };
5432A6032A582D5D00FE2351 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5432A6042A582D6D00FE2351 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
547201942A461554005B2FCC /* PhoneWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PhoneWidget.entitlements; sourceTree = "<group>"; };
547201952A461558005B2FCC /* WatchWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WatchWidget.entitlements; sourceTree = "<group>"; };
548390372A2A773900BF5624 /* JustOneThing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JustOneThing.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -133,8 +152,13 @@
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 /* JustOneThingWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JustOneThingWidget.swift; sourceTree = "<group>"; };
54928C4A2A35F8CB00095445 /* SystemWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemWidget.swift; sourceTree = "<group>"; };
5493A81A2A471E36001EBA08 /* JustOneThingProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JustOneThingProvider.swift; sourceTree = "<group>"; };
54AE28402A5823D900719A56 /* JustOneThingCloudModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = JustOneThingCloudModel.xcdatamodel; sourceTree = "<group>"; };
54AE28462A58245700719A56 /* PersistenceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceController.swift; sourceTree = "<group>"; };
54BD36082A5700480022D6BE /* ThingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThingView.swift; sourceTree = "<group>"; };
54BD360C2A57020E0022D6BE /* WidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBundle.swift; sourceTree = "<group>"; };
54BD36102A57021E0022D6BE /* AccessoryWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryWidget.swift; sourceTree = "<group>"; };
54EB3C1E2A5434A30082B059 /* Thing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Thing.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -196,6 +220,7 @@
5431ED6E2A2A77C900515680 /* JustOneThingWatch */ = {
isa = PBXGroup;
children = (
5432A6042A582D6D00FE2351 /* Info.plist */,
5407E5062A35B96E00EF00B8 /* JustOneThingWatch.entitlements */,
);
path = JustOneThingWatch;
@ -205,7 +230,10 @@
isa = PBXGroup;
children = (
54EB3C1E2A5434A30082B059 /* Thing.swift */,
54928C4A2A35F8CB00095445 /* JustOneThingWidget.swift */,
54BD36082A5700480022D6BE /* ThingView.swift */,
54928C4A2A35F8CB00095445 /* SystemWidget.swift */,
54BD36102A57021E0022D6BE /* AccessoryWidget.swift */,
54BD360C2A57020E0022D6BE /* WidgetBundle.swift */,
5493A81A2A471E36001EBA08 /* JustOneThingProvider.swift */,
5416C7372A56A867002196EE /* InterfaceExtensions.swift */,
54928C372A35F8B800095445 /* WidgetAssets.xcassets */,
@ -218,13 +246,9 @@
5483902E2A2A773900BF5624 = {
isa = PBXGroup;
children = (
5407E5012A2A8A5100EF00B8 /* AppShared */,
548390392A2A773900BF5624 /* JustOneThing */,
5431ED6E2A2A77C900515680 /* JustOneThingWatch */,
5472018B2A3655E4005B2FCC /* WidgetShared */,
54928C192A35F89900095445 /* MacWidget */,
54928C312A35F8B800095445 /* PhoneWidget */,
54928C492A35F8CB00095445 /* WatchWidget */,
54AE283E2A58230400719A56 /* Model */,
54AE283C2A5822C600719A56 /* Apps */,
54AE283D2A5822D400719A56 /* Widgets */,
54928C142A35F89900095445 /* Frameworks */,
548390382A2A773900BF5624 /* Products */,
);
@ -245,6 +269,7 @@
548390392A2A773900BF5624 /* JustOneThing */ = {
isa = PBXGroup;
children = (
5432A6032A582D5D00FE2351 /* Info.plist */,
548390402A2A773A00BF5624 /* JustOneThing.entitlements */,
);
path = JustOneThing;
@ -283,6 +308,36 @@
path = WatchWidget;
sourceTree = "<group>";
};
54AE283C2A5822C600719A56 /* Apps */ = {
isa = PBXGroup;
children = (
5407E5012A2A8A5100EF00B8 /* AppShared */,
548390392A2A773900BF5624 /* JustOneThing */,
5431ED6E2A2A77C900515680 /* JustOneThingWatch */,
);
name = Apps;
sourceTree = "<group>";
};
54AE283D2A5822D400719A56 /* Widgets */ = {
isa = PBXGroup;
children = (
5472018B2A3655E4005B2FCC /* WidgetShared */,
54928C192A35F89900095445 /* MacWidget */,
54928C312A35F8B800095445 /* PhoneWidget */,
54928C492A35F8CB00095445 /* WatchWidget */,
);
name = Widgets;
sourceTree = "<group>";
};
54AE283E2A58230400719A56 /* Model */ = {
isa = PBXGroup;
children = (
54AE283F2A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld */,
54AE28462A58245700719A56 /* PersistenceController.swift */,
);
path = Model;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -476,8 +531,10 @@
buildActionMask = 2147483647;
files = (
5407E5032A2A8AE700EF00B8 /* ContentView.swift in Sources */,
54AE28422A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */,
5407E5022A2A8AE200EF00B8 /* JustOneThingApp.swift in Sources */,
547201932A365868005B2FCC /* Widget.intentdefinition in Sources */,
54AE28482A58245700719A56 /* PersistenceController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -486,8 +543,10 @@
buildActionMask = 2147483647;
files = (
5483903D2A2A773900BF5624 /* ContentView.swift in Sources */,
54AE28412A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */,
5483903B2A2A773900BF5624 /* JustOneThingApp.swift in Sources */,
54928C222A35F89A00095445 /* Widget.intentdefinition in Sources */,
54AE28472A58245700719A56 /* PersistenceController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -495,11 +554,15 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
54AE28492A58245700719A56 /* PersistenceController.swift in Sources */,
54EB3C1F2A5434A30082B059 /* Thing.swift in Sources */,
54928C212A35F89A00095445 /* Widget.intentdefinition in Sources */,
5493A81B2A471E37001EBA08 /* JustOneThingProvider.swift in Sources */,
54BD36092A5700480022D6BE /* ThingView.swift in Sources */,
54BD360D2A57020E0022D6BE /* WidgetBundle.swift in Sources */,
54AE28432A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */,
5416C7382A56A867002196EE /* InterfaceExtensions.swift in Sources */,
547201972A461DBE005B2FCC /* JustOneThingWidget.swift in Sources */,
547201972A461DBE005B2FCC /* SystemWidget.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -507,11 +570,16 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
54BD36122A57021E0022D6BE /* AccessoryWidget.swift in Sources */,
54AE28442A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */,
54EB3C202A5434A30082B059 /* Thing.swift in Sources */,
547201962A461DBE005B2FCC /* JustOneThingWidget.swift in Sources */,
547201962A461DBE005B2FCC /* SystemWidget.swift in Sources */,
5493A81C2A471E37001EBA08 /* JustOneThingProvider.swift in Sources */,
54BD360A2A5700480022D6BE /* ThingView.swift in Sources */,
54BD360E2A57020E0022D6BE /* WidgetBundle.swift in Sources */,
5416C7392A56A867002196EE /* InterfaceExtensions.swift in Sources */,
5472018E2A36563B005B2FCC /* Widget.intentdefinition in Sources */,
54AE284A2A58245700719A56 /* PersistenceController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -519,11 +587,15 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
54AE284B2A58245700719A56 /* PersistenceController.swift in Sources */,
54BD36132A57021E0022D6BE /* AccessoryWidget.swift in Sources */,
54EB3C212A5434A30082B059 /* Thing.swift in Sources */,
547201902A36563C005B2FCC /* Widget.intentdefinition in Sources */,
5493A81D2A471E37001EBA08 /* JustOneThingProvider.swift in Sources */,
54BD360B2A5700480022D6BE /* ThingView.swift in Sources */,
54AE28452A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld in Sources */,
54BD360F2A57020E0022D6BE /* WidgetBundle.swift in Sources */,
5416C73A2A56A867002196EE /* InterfaceExtensions.swift in Sources */,
54928C4B2A35F8CB00095445 /* JustOneThingWidget.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -571,6 +643,7 @@
DEVELOPMENT_TEAM = 37UC5MW6PT;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = JustOneThingWatch/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = JustOneThingWatch;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.alancfrancis.apps.JustOneThing;
@ -603,6 +676,7 @@
DEVELOPMENT_TEAM = 37UC5MW6PT;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = JustOneThingWatch/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = JustOneThingWatch;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.alancfrancis.apps.JustOneThing;
@ -746,6 +820,7 @@
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = JustOneThing/Info.plist;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@ -787,6 +862,7 @@
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = JustOneThing/Info.plist;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@ -820,6 +896,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = MacWidget/MacWidget.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 37UC5MW6PT;
@ -837,6 +914,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.alancfrancis.apps.JustOneThing.MacWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
@ -850,6 +928,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = MacWidget/MacWidget.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 37UC5MW6PT;
@ -867,6 +946,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.alancfrancis.apps.JustOneThing.MacWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
@ -1056,6 +1136,19 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
54AE283F2A5823D900719A56 /* JustOneThingCloudModel.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
54AE28402A5823D900719A56 /* JustOneThingCloudModel.xcdatamodel */,
);
currentVersion = 54AE28402A5823D900719A56 /* JustOneThingCloudModel.xcdatamodel */;
path = JustOneThingCloudModel.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = 5483902F2A2A773900BF5624 /* Project object */;
}

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
</dict>
</plist>

@ -2,10 +2,22 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.alancfrancis.apps.JustOneThing</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array/>
<array>
<string>group.com.alancfrancis.apps.JustOneThing</string>
</array>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
<key>WKBackgroundModes</key>
<array/>
</dict>
</plist>

@ -2,7 +2,19 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.alancfrancis.apps.JustOneThing</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
<key>com.apple.security.application-groups</key>
<array/>
<array>
<string>group.com.alancfrancis.apps.JustOneThing</string>
</array>
</dict>
</plist>

@ -2,7 +2,21 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.alancfrancis.apps.JustOneThing</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.alancfrancis.apps.JustOneThing</string>
</array>
</dict>
</plist>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22F82" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="PersistentThing" representedClassName="PersistentThing" syncable="YES" codeGenerationType="class">
<attribute name="createdAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="text" optional="YES" attributeType="String"/>
<attribute name="uuid" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
</entity>
</model>

@ -0,0 +1,87 @@
//
// PersistenceController.swift
// JustOneThing
//
// Created by Alan Francis on 07/07/2023.
//
import CoreData
//MARK: - URL Extension
// https://developer.apple.com/forums/thread/78120
// There's an issue with tvOS and the path to the local DB.
// This little extension encapsulates that
public extension URL {
/// Returns a URL for the given app group and database pointing to the sqlite database.
static func storeURL(for appGroup: String, databaseName: String) -> URL {
var containerUrl:URL
guard let initialContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else {
fatalError("Shared file container could not be created.")
}
#if os(tvOS)
containerUrl = initialContainer.appendingPathComponent("Library/Caches")
#else
containerUrl = initialContainer
#endif
return containerUrl.appendingPathComponent("\(databaseName).sqlite")
}
}
//MARK: - PeristenceController
struct PersistenceController {
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "JustOneThingCloudModel")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
} else {
let url = URL.storeURL(for: "group.com.alancfrancis.apps.JustOneThing", databaseName: "JustOneThingCloudModel")
container.persistentStoreDescriptions.first!.url = url
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
Self.processError(error:error)
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
//MARK: - static convenience
extension PersistenceController {
static let shared = PersistenceController()
var viewContext:NSManagedObjectContext {
get {
container.viewContext
}
}
}
//MARK: - error handling
extension PersistenceController {
static func processError(error:NSError) {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}

@ -2,7 +2,19 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.alancfrancis.apps.JustOneThing</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
<key>com.apple.security.application-groups</key>
<array/>
<array>
<string>group.com.alancfrancis.apps.JustOneThing</string>
</array>
</dict>
</plist>

@ -2,7 +2,19 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.alancfrancis.apps.JustOneThing</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
<key>com.apple.security.application-groups</key>
<array/>
<array>
<string>group.com.alancfrancis.apps.JustOneThing</string>
</array>
</dict>
</plist>

@ -0,0 +1,40 @@
//
// AccessoryWidget.swift
// JustOneThing
//
// Created by Alan Francis on 06/07/2023.
//
import SwiftUI
import WidgetKit
import Intents
struct JustOneThingAccessoryWidget: Widget {
let kind: String = "JustOneThingAccessoryWidget"
let persistenceController = PersistenceController.shared
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind,
intent: ConfigurationIntent.self,
provider: ThingProvider()) { entry in
JustOneThingAccessoryThingView(thing: entry.thing)
}
.configurationDisplayName("One Tiny Thing")
.description("Show a random Thing in an Accessory.")
.supportedFamilies([.accessoryInline, .accessoryCircular, .accessoryRectangular])
}
}
struct JustOneThingAccessoryThingView: View {
let thing: Thing
@Environment(\.widgetFamily) var family
var body: some View {
if( family == .accessoryCircular ) {
Image(systemName:"1.magnifyingglass").font(.largeTitle)
} else {
ThingView(thing: thing)
}
}
}

@ -1,63 +0,0 @@
//
// JustOneThingWidget.swift
// JustOneThing
//
// Created by Alan Francis on 11/06/2023.
//
import WidgetKit
import SwiftUI
import Intents
@main
struct JustOneThingWidgetBundle: WidgetBundle {
var body: some Widget {
JustOneThingWidget()
}
}
struct ThingView : View {
let thing: Thing
@Environment(\.colorScheme) private var colorScheme
var body: some View {
Text(thing.text)
.fitSystemFont(lineLimit: 4)
.multilineTextAlignment(.center)
.foregroundColor(.randomForegroundColor(colorScheme))
}
}
struct ThingEntryView : View {
var entry: ThingEntry
var body: some View {
ThingView(thing: entry.thing).padding()
}
}
struct JustOneThingWidget: Widget {
let kind: String = "JustOneThingWidget"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind,
intent: ConfigurationIntent.self,
provider: ThingProvider()) { entry in
ThingEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
struct Widget_Previews: PreviewProvider {
static var previews: some View {
ThingEntryView(entry: ThingEntry(thing: Thing(text: "dont forget toothepase", createdAt: Date())))
#if os(watchOS)
.previewContext(WidgetPreviewContext(family: .accessoryCircular))
#else
.previewContext(WidgetPreviewContext(family: .systemMedium))
#endif
}
}

@ -0,0 +1,26 @@
//
// JustOneThingWidget.swift
// JustOneThing
//
// Created by Alan Francis on 11/06/2023.
//
import SwiftUI
import WidgetKit
import Intents
struct JustOneThingSystemWidget: Widget {
let kind: String = "JustOneThingSystemWidget"
let persistenceController = PersistenceController.shared
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind,
intent: ConfigurationIntent.self,
provider: ThingProvider()) { entry in
ThingView(thing: entry.thing)
}
.configurationDisplayName("Just One Thing")
.description("Show a random Thing.")
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
}
}

@ -0,0 +1,21 @@
//
// ThingView.swift
// JustOneThing
//
// Created by Alan Francis on 06/07/2023.
//
import SwiftUI
struct ThingView : View {
let thing: Thing
@Environment(\.colorScheme) private var colorScheme
var body: some View {
Text(thing.text)
.fitSystemFont(lineLimit: 4)
.multilineTextAlignment(.center)
.foregroundColor(.randomForegroundColor(colorScheme))
}
}

@ -0,0 +1,22 @@
//
// WidgetBundle.swift
// JustOneThing
//
// Created by Alan Francis on 06/07/2023.
//
import SwiftUI
import WidgetKit
@main
struct JustOneThingWidgetBundle: WidgetBundle {
var body: some Widget {
#if !os(watchOS)
JustOneThingSystemWidget()
#endif
#if !os(macOS)
JustOneThingAccessoryWidget()
#endif
}
}
Loading…
Cancel
Save