From 5d60a4049e3f13bc6b3c27f98f907de9b31afdd3 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Sun, 24 May 2026 16:09:37 +0200 Subject: [PATCH] =?UTF-8?q?feat(watchos):=20target=20CoachWatch=20(Phase?= =?UTF-8?q?=201)=20=E2=80=94=20app=20watchOS=20embarqu=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - nouvelle target watchOS app CoachWatch (ch.hypnotruck.coach.watchkitapp), SwiftUI, SDK watchos - entitlement HealthKit + Info.plist FR (NSHealthShare/UpdateUsageDescription) + WKBackgroundModes workout-processing - "Embed Watch Content" + dépendance App -> CoachWatch (CoachWatch.app dans App.app/Watch) - schemes partagés App + CoachWatch - CoachWatchApp.swift + ContentView.swift minimaux Build validé: target watchsimulator + embed dans App.app (iphonesimulator). Co-Authored-By: Claude Opus 4.7 (1M context) --- ios/App/App.xcodeproj/project.pbxproj | 190 ++++++++++++++++++ .../xcshareddata/xcschemes/App.xcscheme | 87 ++++++++ .../xcschemes/CoachWatch.xcscheme | 87 ++++++++ ios/App/CoachWatch/CoachWatch.entitlements | 10 + ios/App/CoachWatch/CoachWatchApp.swift | 10 + ios/App/CoachWatch/ContentView.swift | 20 ++ ios/App/CoachWatch/Info.plist | 34 ++++ 7 files changed, 438 insertions(+) create mode 100644 ios/App/App.xcodeproj/xcshareddata/xcschemes/App.xcscheme create mode 100644 ios/App/App.xcodeproj/xcshareddata/xcschemes/CoachWatch.xcscheme create mode 100644 ios/App/CoachWatch/CoachWatch.entitlements create mode 100644 ios/App/CoachWatch/CoachWatchApp.swift create mode 100644 ios/App/CoachWatch/ContentView.swift create mode 100644 ios/App/CoachWatch/Info.plist diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index 1d2cc09..1cb1c67 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -7,7 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 01468471ECA28EA66AFE2D6C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EB6C76F68679844EC72178F /* Foundation.framework */; }; + 290D0F17978B7EF3DDB3A792 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A06CDFF5B4F7852B6329862 /* ContentView.swift */; }; 2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; }; + 3E6740C521EF14892687BCF7 /* CoachWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 2517374227A4072A4D6AFC15 /* CoachWatch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 4D22ABE92AF431CB00220026 /* CapApp-SPM in Frameworks */ = {isa = PBXBuildFile; productRef = 4D22ABE82AF431CB00220026 /* CapApp-SPM */; }; 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; }; 504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; }; @@ -15,6 +18,7 @@ 504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; }; 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; }; 50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; }; + 543A7005429A43F54C0EC61B /* CoachWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BEAEF6F6274D61CAF22636 /* CoachWatchApp.swift */; }; 88F28EB12FBB330E00E8306E /* CoachWorkoutObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88F28EB02FBB330E00E8306E /* CoachWorkoutObserver.swift */; }; C0AC4A07811751FB78AA0001 /* CoachAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0AC4A07811751FB78AA0002 /* CoachAuth.swift */; }; D1BD5B1990CF3F2B9C5D0001 /* CoachWorkoutKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BD5B1990CF3F2B9C5D0002 /* CoachWorkoutKit.swift */; }; @@ -22,7 +26,33 @@ F1ABCDEF0123456789AB0001 /* CoachHealthRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1ABCDEF0123456789AB0002 /* CoachHealthRoute.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 3063F4D3E3903D2EB4956B44 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 504EC2FC1FED79650016851F /* Project object */; + proxyType = 1; + remoteGlobalIDString = D5BF41648D334DC24770B9D2; + remoteInfo = CoachWatch; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F50D9A7DFABB52EE96BB93D6 /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + 3E6740C521EF14892687BCF7 /* CoachWatch.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ + 0EB6C76F68679844EC72178F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS11.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 2517374227A4072A4D6AFC15 /* CoachWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoachWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = ""; }; 50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = ""; }; 504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -32,13 +62,17 @@ 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; }; + 82122ACF7E5A608AD1D55D24 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 88A837392FAA741C00DDD144 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = ""; }; 88F28EB02FBB330E00E8306E /* CoachWorkoutObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoachWorkoutObserver.swift; sourceTree = ""; }; + 8A06CDFF5B4F7852B6329862 /* ContentView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 958DCC722DB07C7200EA8C5F /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = debug.xcconfig; path = ../debug.xcconfig; sourceTree = SOURCE_ROOT; }; C0AC4A07811751FB78AA0002 /* CoachAuth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoachAuth.swift; sourceTree = ""; }; + D09B589FA572B2C14E8CD835 /* CoachWatch.entitlements */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.entitlements; path = CoachWatch.entitlements; sourceTree = ""; }; D1BD5B1990CF3F2B9C5D0002 /* CoachWorkoutKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoachWorkoutKit.swift; sourceTree = ""; }; E2CE6C2AA1DF4F3CAD6E0002 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; F1ABCDEF0123456789AB0002 /* CoachHealthRoute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoachHealthRoute.swift; sourceTree = ""; }; + F6BEAEF6F6274D61CAF22636 /* CoachWatchApp.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CoachWatchApp.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -50,15 +84,33 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 85FFFE3727FD44280013FE19 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 01468471ECA28EA66AFE2D6C /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 3E58B60E9B4F1CA14B5EC667 /* watchOS */ = { + isa = PBXGroup; + children = ( + 0EB6C76F68679844EC72178F /* Foundation.framework */, + ); + name = watchOS; + sourceTree = ""; + }; 504EC2FB1FED79650016851F = { isa = PBXGroup; children = ( 958DCC722DB07C7200EA8C5F /* debug.xcconfig */, 504EC3061FED79650016851F /* App */, 504EC3051FED79650016851F /* Products */, + B91ACF72653FD495148698CF /* Frameworks */, + 5A8EA0CF92316E437E9053A0 /* CoachWatch */, ); sourceTree = ""; }; @@ -66,6 +118,7 @@ isa = PBXGroup; children = ( 504EC3041FED79650016851F /* App.app */, + 2517374227A4072A4D6AFC15 /* CoachWatch.app */, ); name = Products; sourceTree = ""; @@ -91,6 +144,26 @@ path = App; sourceTree = ""; }; + 5A8EA0CF92316E437E9053A0 /* CoachWatch */ = { + isa = PBXGroup; + children = ( + F6BEAEF6F6274D61CAF22636 /* CoachWatchApp.swift */, + 8A06CDFF5B4F7852B6329862 /* ContentView.swift */, + 82122ACF7E5A608AD1D55D24 /* Info.plist */, + D09B589FA572B2C14E8CD835 /* CoachWatch.entitlements */, + ); + name = CoachWatch; + path = CoachWatch; + sourceTree = ""; + }; + B91ACF72653FD495148698CF /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3E58B60E9B4F1CA14B5EC667 /* watchOS */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -101,10 +174,12 @@ 504EC3001FED79650016851F /* Sources */, 504EC3011FED79650016851F /* Frameworks */, 504EC3021FED79650016851F /* Resources */, + F50D9A7DFABB52EE96BB93D6 /* Embed Watch Content */, ); buildRules = ( ); dependencies = ( + EEEAB45810829EE8B3C4976E /* PBXTargetDependency */, ); name = App; packageProductDependencies = ( @@ -114,6 +189,23 @@ productReference = 504EC3041FED79650016851F /* App.app */; productType = "com.apple.product-type.application"; }; + D5BF41648D334DC24770B9D2 /* CoachWatch */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA2A9602402AA384726BFF97 /* Build configuration list for PBXNativeTarget "CoachWatch" */; + buildPhases = ( + E1B262849E79F8569984E173 /* Sources */, + 85FFFE3727FD44280013FE19 /* Frameworks */, + CFD58983FA62853BAD4DC405 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CoachWatch; + productName = CoachWatch; + productReference = 2517374227A4072A4D6AFC15 /* CoachWatch.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -147,6 +239,7 @@ projectRoot = ""; targets = ( 504EC3031FED79650016851F /* App */, + D5BF41648D334DC24770B9D2 /* CoachWatch */, ); }; /* End PBXProject section */ @@ -165,6 +258,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CFD58983FA62853BAD4DC405 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -181,8 +281,26 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + E1B262849E79F8569984E173 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 543A7005429A43F54C0EC61B /* CoachWatchApp.swift in Sources */, + 290D0F17978B7EF3DDB3A792 /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + EEEAB45810829EE8B3C4976E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CoachWatch; + target = D5BF41648D334DC24770B9D2 /* CoachWatch */; + targetProxy = 3063F4D3E3903D2EB4956B44 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 504EC30B1FED79650016851F /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -203,6 +321,37 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 09CEF8C9131E8948450FEC27 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = CoachWatch/CoachWatch.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 22; + DEVELOPMENT_TEAM = TZ2PVTRKNY; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = NO; + INFOPLIST_FILE = CoachWatch/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.2; + PRODUCT_BUNDLE_IDENTIFIER = ch.hypnotruck.coach.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 11.0; + }; + name = Debug; + }; 504EC3141FED79650016851F /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 958DCC722DB07C7200EA8C5F /* debug.xcconfig */; @@ -364,6 +513,38 @@ }; name = Release; }; + 6BD679ED799FBBFC9D3BE40C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = CoachWatch/CoachWatch.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 22; + DEVELOPMENT_TEAM = TZ2PVTRKNY; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = NO; + INFOPLIST_FILE = CoachWatch/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.2; + PRODUCT_BUNDLE_IDENTIFIER = ch.hypnotruck.coach.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 11.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -385,6 +566,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + FA2A9602402AA384726BFF97 /* Build configuration list for PBXNativeTarget "CoachWatch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6BD679ED799FBBFC9D3BE40C /* Release */, + 09CEF8C9131E8948450FEC27 /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ diff --git a/ios/App/App.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/ios/App/App.xcodeproj/xcshareddata/xcschemes/App.xcscheme new file mode 100644 index 0000000..e5264ba --- /dev/null +++ b/ios/App/App.xcodeproj/xcshareddata/xcschemes/App.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/App/App.xcodeproj/xcshareddata/xcschemes/CoachWatch.xcscheme b/ios/App/App.xcodeproj/xcshareddata/xcschemes/CoachWatch.xcscheme new file mode 100644 index 0000000..006e9e0 --- /dev/null +++ b/ios/App/App.xcodeproj/xcshareddata/xcschemes/CoachWatch.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/App/CoachWatch/CoachWatch.entitlements b/ios/App/CoachWatch/CoachWatch.entitlements new file mode 100644 index 0000000..2ab14a2 --- /dev/null +++ b/ios/App/CoachWatch/CoachWatch.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.healthkit + + com.apple.developer.healthkit.access + + + diff --git a/ios/App/CoachWatch/CoachWatchApp.swift b/ios/App/CoachWatch/CoachWatchApp.swift new file mode 100644 index 0000000..21cfacd --- /dev/null +++ b/ios/App/CoachWatch/CoachWatchApp.swift @@ -0,0 +1,10 @@ +import SwiftUI + +@main +struct CoachWatchApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/ios/App/CoachWatch/ContentView.swift b/ios/App/CoachWatch/ContentView.swift new file mode 100644 index 0000000..a493fec --- /dev/null +++ b/ios/App/CoachWatch/ContentView.swift @@ -0,0 +1,20 @@ +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack(spacing: 8) { + Image(systemName: "heart.fill") + .foregroundStyle(.red) + Text("Coach") + .font(.headline) + Text("Prêt") + .font(.caption) + .foregroundStyle(.secondary) + } + .padding() + } +} + +#Preview { + ContentView() +} diff --git a/ios/App/CoachWatch/Info.plist b/ios/App/CoachWatch/Info.plist new file mode 100644 index 0000000..b3715c8 --- /dev/null +++ b/ios/App/CoachWatch/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Coach + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + WKApplication + + WKBackgroundModes + + workout-processing + + NSHealthShareUsageDescription + Coach Hypnotruck lit ta fréquence cardiaque et tes calories pendant la séance pour les afficher en direct sur ton iPhone. + NSHealthUpdateUsageDescription + Coach Hypnotruck enregistre ta séance dans l'app Santé. + +