From 3ac5d527cdd362cd21a4886ef4fb671baa16443b Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sun, 5 Jul 2026 17:40:56 +0200 Subject: [PATCH] Created the Sample app widget target in the Xcode project. --- Attendi.xcodeproj/project.pbxproj | 310 +++++++++++++++++- .../xcshareddata/xcschemes/Attendi.xcscheme | 79 +++++ .../xcschemes/AttendiWidgetExtension.xcscheme | 115 +++++++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 85 +++++ .../Catalogs/Assets.xcassets/Contents.json | 6 + .../WidgetBackground.colorset/Contents.json | 11 + Widgets/Attendi/Resources/Info.plist | 11 + .../Sources/Bundle/AttendiWidgetBundle.swift | 9 + .../Attendi/Sources/Intents/AppIntent.swift | 11 + Widgets/Attendi/Widgets/AttendiWidget.swift | 79 +++++ 11 files changed, 717 insertions(+), 10 deletions(-) create mode 100644 Attendi.xcodeproj/xcshareddata/xcschemes/Attendi.xcscheme create mode 100644 Attendi.xcodeproj/xcshareddata/xcschemes/AttendiWidgetExtension.xcscheme create mode 100644 Widgets/Attendi/Catalogs/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Widgets/Attendi/Catalogs/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Widgets/Attendi/Catalogs/Assets.xcassets/Contents.json create mode 100644 Widgets/Attendi/Catalogs/Assets.xcassets/WidgetBackground.colorset/Contents.json create mode 100644 Widgets/Attendi/Resources/Info.plist create mode 100644 Widgets/Attendi/Sources/Bundle/AttendiWidgetBundle.swift create mode 100644 Widgets/Attendi/Sources/Intents/AppIntent.swift create mode 100644 Widgets/Attendi/Widgets/AttendiWidget.swift diff --git a/Attendi.xcodeproj/project.pbxproj b/Attendi.xcodeproj/project.pbxproj index 6d47f00..80f974e 100644 --- a/Attendi.xcodeproj/project.pbxproj +++ b/Attendi.xcodeproj/project.pbxproj @@ -9,6 +9,9 @@ /* Begin PBXBuildFile section */ 02870A252FF7F07F0079EA3A /* Features in Frameworks */ = {isa = PBXBuildFile; productRef = 02870A242FF7F07F0079EA3A /* Features */; }; 02870A292FF7FF530079EA3A /* Features in Frameworks */ = {isa = PBXBuildFile; productRef = 02870A282FF7FF530079EA3A /* Features */; }; + 0296F7F02FFAB1B600D2C5FC /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0296F7EF2FFAB1B600D2C5FC /* WidgetKit.framework */; }; + 0296F7F22FFAB1B600D2C5FC /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0296F7F12FFAB1B600D2C5FC /* SwiftUI.framework */; }; + 0296F7FF2FFAB1B600D2C5FC /* AttendiWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0296F7EE2FFAB1B600D2C5FC /* AttendiWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -19,13 +22,35 @@ remoteGlobalIDString = 02870A0C2FF7EB610079EA3A; remoteInfo = Attendi; }; + 0296F7FD2FFAB1B600D2C5FC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 028709F22FF7E8E40079EA3A /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0296F7ED2FFAB1B600D2C5FC; + remoteInfo = AttendiWidgetExtension; + }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 0296F8042FFAB1B600D2C5FC /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + dstPath = ""; + dstSubfolder = PlugIns; + files = ( + 0296F7FF2FFAB1B600D2C5FC /* AttendiWidgetExtension.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 02870A0D2FF7EB610079EA3A /* Attendi.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Attendi.app; sourceTree = BUILT_PRODUCTS_DIR; }; 02870A262FF7F2990079EA3A /* README.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = README.pdf; sourceTree = ""; }; 02870A322FF831CD0079EA3A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 0296F79A2FFA954E00D2C5FC /* AttendiTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AttendiTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 0296F7EE2FFAB1B600D2C5FC /* AttendiWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = AttendiWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 0296F7EF2FFAB1B600D2C5FC /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = /System/Library/Frameworks/WidgetKit.framework; sourceTree = ""; }; + 0296F7F12FFAB1B600D2C5FC /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = /System/Library/Frameworks/SwiftUI.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ @@ -49,6 +74,16 @@ ); target = 0296F7992FFA954E00D2C5FC /* AttendiTests */; }; + 02D46AC12FFAB2C300266643 /* Exceptions for "Widgets" folder in "AttendiWidgetExtension" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Attendi/Catalogs/Assets.xcassets, + Attendi/Sources/Bundle/AttendiWidgetBundle.swift, + Attendi/Sources/Intents/AppIntent.swift, + Attendi/Widgets/AttendiWidget.swift, + ); + target = 0296F7ED2FFAB1B600D2C5FC /* AttendiWidgetExtension */; + }; /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ @@ -66,6 +101,14 @@ path = Packages; sourceTree = ""; }; + 02D46AB62FFAB2B900266643 /* Widgets */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 02D46AC12FFAB2C300266643 /* Exceptions for "Widgets" folder in "AttendiWidgetExtension" target */, + ); + path = Widgets; + sourceTree = ""; + }; /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ @@ -81,6 +124,13 @@ files = ( ); }; + 0296F7EB2FFAB1B600D2C5FC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + files = ( + 0296F7F22FFAB1B600D2C5FC /* SwiftUI.framework in Frameworks */, + 0296F7F02FFAB1B600D2C5FC /* WidgetKit.framework in Frameworks */, + ); + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -90,6 +140,7 @@ 02870A322FF831CD0079EA3A /* README.md */, 02870A202FF7ECD00079EA3A /* Packages */, 02870A082FF7EB360079EA3A /* Apps */, + 02D46AB62FFAB2B900266643 /* Widgets */, 02870A232FF7F07F0079EA3A /* Frameworks */, 028709FD2FF7EAB50079EA3A /* Products */, 02870A262FF7F2990079EA3A /* README.pdf */, @@ -101,6 +152,7 @@ children = ( 02870A0D2FF7EB610079EA3A /* Attendi.app */, 0296F79A2FFA954E00D2C5FC /* AttendiTests.xctest */, + 0296F7EE2FFAB1B600D2C5FC /* AttendiWidgetExtension.appex */, ); name = Products; sourceTree = ""; @@ -108,6 +160,8 @@ 02870A232FF7F07F0079EA3A /* Frameworks */ = { isa = PBXGroup; children = ( + 0296F7EF2FFAB1B600D2C5FC /* WidgetKit.framework */, + 0296F7F12FFAB1B600D2C5FC /* SwiftUI.framework */, ); name = Frameworks; sourceTree = ""; @@ -122,9 +176,13 @@ 02870A092FF7EB610079EA3A /* Sources */, 02870A0A2FF7EB610079EA3A /* Frameworks */, 02870A0B2FF7EB610079EA3A /* Resources */, + 0296F8042FFAB1B600D2C5FC /* Embed Foundation Extensions */, ); buildRules = ( ); + dependencies = ( + 0296F7FE2FFAB1B600D2C5FC /* PBXTargetDependency */, + ); name = Attendi; packageProductDependencies = ( 02870A242FF7F07F0079EA3A /* Features */, @@ -152,6 +210,21 @@ productReference = 0296F79A2FFA954E00D2C5FC /* AttendiTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 0296F7ED2FFAB1B600D2C5FC /* AttendiWidgetExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0296F8002FFAB1B600D2C5FC /* Build configuration list for PBXNativeTarget "AttendiWidgetExtension" */; + buildPhases = ( + 0296F7EA2FFAB1B600D2C5FC /* Sources */, + 0296F7EB2FFAB1B600D2C5FC /* Frameworks */, + 0296F7EC2FFAB1B600D2C5FC /* Resources */, + ); + buildRules = ( + ); + name = AttendiWidgetExtension; + productName = AttendiWidgetExtension; + productReference = 0296F7EE2FFAB1B600D2C5FC /* AttendiWidgetExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -170,6 +243,9 @@ CreatedOnToolsVersion = 26.6; TestTargetID = 02870A0C2FF7EB610079EA3A; }; + 0296F7ED2FFAB1B600D2C5FC = { + CreatedOnToolsVersion = 26.6; + }; }; }; buildConfigurationList = 028709F52FF7E8E40079EA3A /* Build configuration list for PBXProject "Attendi" */; @@ -191,6 +267,7 @@ targets = ( 02870A0C2FF7EB610079EA3A /* Attendi */, 0296F7992FFA954E00D2C5FC /* AttendiTests */, + 0296F7ED2FFAB1B600D2C5FC /* AttendiWidgetExtension */, ); }; /* End PBXProject section */ @@ -206,6 +283,11 @@ files = ( ); }; + 0296F7EC2FFAB1B600D2C5FC /* Resources */ = { + isa = PBXResourcesBuildPhase; + files = ( + ); + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -219,6 +301,11 @@ files = ( ); }; + 0296F7EA2FFAB1B600D2C5FC /* Sources */ = { + isa = PBXSourcesBuildPhase; + files = ( + ); + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -227,6 +314,11 @@ target = 02870A0C2FF7EB610079EA3A /* Attendi */; targetProxy = 0296F79E2FFA954E00D2C5FC /* PBXContainerItemProxy */; }; + 0296F7FE2FFAB1B600D2C5FC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0296F7ED2FFAB1B600D2C5FC /* AttendiWidgetExtension */; + targetProxy = 0296F7FD2FFAB1B600D2C5FC /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -529,14 +621,14 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 26.5; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 26.5; + MACOSX_DEPLOYMENT_TARGET = 26.0; MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.rock-n-code.app.AttendiTests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.rock-n-code.app.attendi.sample.tests.unit"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; STRING_CATALOG_GENERATE_SYMBOLS = NO; @@ -546,10 +638,10 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2,7"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Attendi.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Attendi"; - XROS_DEPLOYMENT_TARGET = 26.5; + XROS_DEPLOYMENT_TARGET = 26.0; }; name = Debug; }; @@ -604,13 +696,13 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 26.5; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 26.5; + MACOSX_DEPLOYMENT_TARGET = 26.0; MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.rock-n-code.app.AttendiTests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.rock-n-code.app.attendi.sample.tests.unit"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; STRING_CATALOG_GENERATE_SYMBOLS = NO; @@ -619,10 +711,200 @@ SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2,7"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Attendi.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Attendi"; - XROS_DEPLOYMENT_TARGET = 26.5; + XROS_DEPLOYMENT_TARGET = 26.0; + }; + name = Release; + }; + 0296F8012FFAB1B600D2C5FC /* Debug configuration for PBXNativeTarget "AttendiWidgetExtension" */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 7FMNM89WKG; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Widgets/Attendi/Resources/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Attendi; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 Röck+Cöde VoF. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@executable_path/../../../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 26.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.rock-n-code.app.attendi.sample.widget"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2,4,7"; + WATCHOS_DEPLOYMENT_TARGET = 26.0; + XROS_DEPLOYMENT_TARGET = 26.0; + }; + name = Debug; + }; + 0296F8022FFAB1B600D2C5FC /* Release configuration for PBXNativeTarget "AttendiWidgetExtension" */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 7FMNM89WKG; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Widgets/Attendi/Resources/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Attendi; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 Röck+Cöde VoF. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@executable_path/../../../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 26.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.rock-n-code.app.attendi.sample.widget"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2,4,7"; + WATCHOS_DEPLOYMENT_TARGET = 26.0; + XROS_DEPLOYMENT_TARGET = 26.0; }; name = Release; }; @@ -653,6 +935,14 @@ ); defaultConfigurationName = Release; }; + 0296F8002FFAB1B600D2C5FC /* Build configuration list for PBXNativeTarget "AttendiWidgetExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0296F8012FFAB1B600D2C5FC /* Debug configuration for PBXNativeTarget "AttendiWidgetExtension" */, + 0296F8022FFAB1B600D2C5FC /* Release configuration for PBXNativeTarget "AttendiWidgetExtension" */, + ); + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ diff --git a/Attendi.xcodeproj/xcshareddata/xcschemes/Attendi.xcscheme b/Attendi.xcodeproj/xcshareddata/xcschemes/Attendi.xcscheme new file mode 100644 index 0000000..0d81a64 --- /dev/null +++ b/Attendi.xcodeproj/xcshareddata/xcschemes/Attendi.xcscheme @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Attendi.xcodeproj/xcshareddata/xcschemes/AttendiWidgetExtension.xcscheme b/Attendi.xcodeproj/xcshareddata/xcschemes/AttendiWidgetExtension.xcscheme new file mode 100644 index 0000000..4dc9164 --- /dev/null +++ b/Attendi.xcodeproj/xcshareddata/xcschemes/AttendiWidgetExtension.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Widgets/Attendi/Catalogs/Assets.xcassets/AccentColor.colorset/Contents.json b/Widgets/Attendi/Catalogs/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Widgets/Attendi/Catalogs/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widgets/Attendi/Catalogs/Assets.xcassets/AppIcon.appiconset/Contents.json b/Widgets/Attendi/Catalogs/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..ffdfe15 --- /dev/null +++ b/Widgets/Attendi/Catalogs/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,85 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widgets/Attendi/Catalogs/Assets.xcassets/Contents.json b/Widgets/Attendi/Catalogs/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Widgets/Attendi/Catalogs/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widgets/Attendi/Catalogs/Assets.xcassets/WidgetBackground.colorset/Contents.json b/Widgets/Attendi/Catalogs/Assets.xcassets/WidgetBackground.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Widgets/Attendi/Catalogs/Assets.xcassets/WidgetBackground.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widgets/Attendi/Resources/Info.plist b/Widgets/Attendi/Resources/Info.plist new file mode 100644 index 0000000..0f118fb --- /dev/null +++ b/Widgets/Attendi/Resources/Info.plist @@ -0,0 +1,11 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/Widgets/Attendi/Sources/Bundle/AttendiWidgetBundle.swift b/Widgets/Attendi/Sources/Bundle/AttendiWidgetBundle.swift new file mode 100644 index 0000000..b31ab27 --- /dev/null +++ b/Widgets/Attendi/Sources/Bundle/AttendiWidgetBundle.swift @@ -0,0 +1,9 @@ +import WidgetKit +import SwiftUI + +@main +struct AttendiWidgetBundle: WidgetBundle { + var body: some Widget { + AttendiWidget() + } +} diff --git a/Widgets/Attendi/Sources/Intents/AppIntent.swift b/Widgets/Attendi/Sources/Intents/AppIntent.swift new file mode 100644 index 0000000..35f1b88 --- /dev/null +++ b/Widgets/Attendi/Sources/Intents/AppIntent.swift @@ -0,0 +1,11 @@ +import WidgetKit +import AppIntents + +struct ConfigurationAppIntent: WidgetConfigurationIntent { + static var title: LocalizedStringResource { "Configuration" } + static var description: IntentDescription { "This is an example widget." } + + // An example configurable parameter. + @Parameter(title: "Favorite Emoji", default: "😃") + var favoriteEmoji: String +} diff --git a/Widgets/Attendi/Widgets/AttendiWidget.swift b/Widgets/Attendi/Widgets/AttendiWidget.swift new file mode 100644 index 0000000..b2a9282 --- /dev/null +++ b/Widgets/Attendi/Widgets/AttendiWidget.swift @@ -0,0 +1,79 @@ +import WidgetKit +import SwiftUI + +struct Provider: AppIntentTimelineProvider { + func placeholder(in context: Context) -> SimpleEntry { + SimpleEntry(date: Date(), configuration: ConfigurationAppIntent()) + } + + func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry { + SimpleEntry(date: Date(), configuration: configuration) + } + + func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> 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) + } + + return Timeline(entries: entries, policy: .atEnd) + } + +// func relevances() async -> WidgetRelevances { +// // Generate a list containing the contexts this widget is relevant in. +// } +} + +struct SimpleEntry: TimelineEntry { + let date: Date + let configuration: ConfigurationAppIntent +} + +struct AttendiWidgetEntryView : View { + var entry: Provider.Entry + + var body: some View { + Text("Time:") + Text(entry.date, style: .time) + + Text("Favorite Emoji:") + Text(entry.configuration.favoriteEmoji) + } +} + +struct AttendiWidget: Widget { + let kind: String = "AttendiWidget" + + var body: some WidgetConfiguration { + AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in + AttendiWidgetEntryView(entry: entry) + .containerBackground(.fill.tertiary, for: .widget) + } + } +} + +extension ConfigurationAppIntent { + fileprivate static var smiley: ConfigurationAppIntent { + let intent = ConfigurationAppIntent() + intent.favoriteEmoji = "😀" + return intent + } + + fileprivate static var starEyes: ConfigurationAppIntent { + let intent = ConfigurationAppIntent() + intent.favoriteEmoji = "🤩" + return intent + } +} + +#Preview(as: .systemSmall) { + AttendiWidget() +} timeline: { + SimpleEntry(date: .now, configuration: .smiley) + SimpleEntry(date: .now, configuration: .starEyes) +}