diff --git a/.gitea/workflows/pr-iphone-deploy.yml b/.gitea/workflows/pr-iphone-deploy.yml new file mode 100644 index 0000000..761dfec --- /dev/null +++ b/.gitea/workflows/pr-iphone-deploy.yml @@ -0,0 +1,191 @@ +# ============================================================================= +# TabataGo — PR → Build → Archive → Firebase OTA → Wait LGTM → Merge +# ============================================================================= + +name: PR → Build → Firebase OTA → LGTM + +on: + pull_request: + branches: [main] + types: [opened, synchronize, reopened] + +permissions: + contents: write + pull-requests: write + +jobs: + + build-deploy: + name: Build & Deploy to Firebase OTA + runs-on: macos + timeout-minutes: 20 + + steps: + - name: Checkout + run: | + git clone --depth 1 -b ${{ github.head_ref }} https://x-access-token:${PR_TOKEN}@gitea.1000co.fr/${REPO}.git . + env: + PR_TOKEN: ${{ secrets.PR_API_TOKEN }} + REPO: ${{ github.repository }} + + - name: Setup Xcode + run: | + xcodebuild -version + + - name: Setup PATH + run: echo "/opt/homebrew/bin" >> $GITHUB_PATH + + - name: Clean build artifacts + run: | + echo "🧹 Cleaning build artifacts..." + + # Act runner caches + rm -rf ~/.cache/act/*/hostexecutor/tabatago-swift/build 2>/dev/null || true + + # SPM caches are KEPT between runs — RevenueCat is 1.10 GiB and takes + # 5+ minutes to clone; re-cloning on every CI run would waste time + # and cause random failures on the act_runner sandbox. + + # Xcode DerivedData — suppression COMPLÈTE (le bundle ID a changé, + # l'ancien dossier TabataGo-* peut être ignoré par le nouveau build) + rm -rf ~/Library/Developer/Xcode/DerivedData/* + + # Module cache Xcode — des .pcm stale peuvent segfault le linker + rm -rf ~/Library/Developer/Xcode/DerivedData/ModuleCache.noindex 2>/dev/null || true + rm -rf ~/Library/Caches/com.apple.dt.Xcode + + # Build artifacts locaux (utilisés par le step "Build app") + rm -rf build/ + rm -rf .build + rm -rf tabatago-swift/.build + rm -rf tabatago-swift/TabataGo.xcodeproj + rm -rf tabatago-swift/*.xcworkspace 2>/dev/null || true + + # Package.resolved — peut être stale après un changement de bundle ID + find . -name "Package.resolved" -delete 2>/dev/null || true + find . -name ".package.resolved" -delete 2>/dev/null || true + + echo "✅ Caches nettoyés" + + - name: Install tools (xcodegen, node, firebase) + run: | + brew install xcodegen node || true + npm install -g firebase-tools + + - name: Generate Xcode project + run: | + cd tabatago-swift + xcodegen generate + + - name: Resolve SPM packages + run: | + cd tabatago-swift + xcodebuild -resolvePackageDependencies \ + -project TabataGo.xcodeproj \ + -scmProvider system + + - name: Build app + run: | + cd tabatago-swift + xcodebuild -list + xcodebuild build \ + -project TabataGo.xcodeproj \ + -scheme TabataGo \ + -configuration Debug \ + -allowProvisioningUpdates \ + -skipPackagePluginValidation \ + -derivedDataPath ../build/derived \ + -clonedSourcePackagesDirPath ../build/spm-cache \ + SWIFT_ENABLE_EXPLICIT_MODULES=NO \ + ONLY_ACTIVE_ARCH=NO \ + CODE_SIGN_STYLE=Automatic \ + DEVELOPMENT_TEAM=2MJF39L8VY + + - name: Package IPA + run: | + cd tabatago-swift + mkdir -p Payload build + APP=$(find ../build/derived -name 'TabataGo.app' -type d | head -1) + cp -R "$APP" Payload/ + zip -r build/TabataGo.ipa Payload/ + rm -rf Payload + + - name: Deploy to Firebase + env: + FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }} + FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} + run: | + npx firebase appdistribution:distribute tabatago-swift/build/TabataGo.ipa \ + --app "${FIREBASE_APP_ID}" \ + --groups "millian-test" \ + --project tabatago-19a80 \ + --token "${FIREBASE_TOKEN}" \ + --release-notes "PR: ${{ github.event.pull_request.title }}" + + - name: Post "Ready to test" comment + env: + GT_TOKEN: ${{ secrets.PR_API_TOKEN }} + GITEA_URL: https://gitea.1000co.fr + run: | + PR="${{ github.event.pull_request.number }}" + REPO="${{ github.repository }}" + curl -s -X POST \ + -H "Authorization: token ${GT_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"body\":\"## 📱 Prêt à tester !\\n\\nL\'app est déployée via Firebase.\\n\\n- Teste les changements\\n- Reply **LGTM** pour merger\\n- Reply **KO** pour bloquer\"}" \ + "${GITEA_URL}/api/v1/repos/${REPO}/issues/${PR}/comments" + + wait-approval: + name: Wait for LGTM comment + needs: build-deploy + runs-on: macos + timeout-minutes: 120 + + steps: + - name: Poll for LGTM + env: + GT_TOKEN: ${{ secrets.PR_API_TOKEN }} + GITEA_URL: https://gitea.1000co.fr + run: | + PR="${{ github.event.pull_request.number }}" + REPO="${{ github.repository }}" + PR_TITLE="${{ github.event.pull_request.title }}" + API="${GITEA_URL}/api/v1/repos/${REPO}" + MAX=240 + TRIES=0 + + echo "⏳ Attente LGTM sur PR #${PR}..." + + LAST_ID=$(curl -s -H "Authorization: token ${GT_TOKEN}" \ + "${API}/issues/${PR}/comments" | \ + python3 -c "import json,sys; cs=json.load(sys.stdin); print(cs[-1]['id'] if cs else 0)" 2>/dev/null || echo 0) + + while [ $TRIES -lt $MAX ]; do + sleep 30 + TRIES=$((TRIES + 1)) + + COMMENTS=$(curl -s -H "Authorization: token ${GT_TOKEN}" \ + "${API}/issues/${PR}/comments?since_id=${LAST_ID}") + + if echo "$COMMENTS" | grep -qi '"body": *"LGTM"'; then + echo "✅ LGTM reçu ! Merge..." + curl -s -X POST \ + -H "Authorization: token ${GT_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"Do\":\"merge\"}" \ + "${API}/pulls/${PR}/merge" + echo "✅ Mergée." + exit 0 + fi + + if echo "$COMMENTS" | grep -qi '"body": *"KO"'; then + echo "❌ KO reçu. Bloquée." + exit 1 + fi + + if [ $((TRIES % 4)) -eq 0 ]; then + echo " ⏳ ... (${TRIES}/240, $(date +%H:%M))" + fi + done + echo "❌ Timeout 2h." + exit 1 diff --git a/.gitignore b/.gitignore index 9113d6f..d3e56b8 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,11 @@ Config/Secrets.xcconfig _Users_* swift-generated-sources/ tabatago-swift/build/ + +# Swift Package Manager +Package.resolved +.build/ +DerivedData/ + +# XcodeGen generated — NOT in version control +TabataGo.xcodeproj diff --git a/docs/app-store-submission.md b/docs/app-store-submission.md index 90a910e..8d63f9b 100644 --- a/docs/app-store-submission.md +++ b/docs/app-store-submission.md @@ -44,7 +44,7 @@ Or run manually: 2. Archives the app with Xcode auto-signing 3. Exports an App Store IPA 4. Uploads to App Store Connect -5. The first upload **automatically creates** the app record in App Store Connect (bundle ID: `com.tabatago.app`) +5. The first upload **automatically creates** the app record in App Store Connect (bundle ID: `fr.millianlmx.tabatago`) ## After Upload @@ -60,7 +60,7 @@ Or run manually: | Symptom | Likely Cause | |---|---| | "No accounts with iTunes Connect access" | API key doesn't have App Manager permissions — recreate the key with correct access | -| "No profiles found" | The bundle ID `com.tabatago.app` isn't registered yet — check Apple Developer portal | +| "No profiles found" | The bundle ID `fr.millianlmx.tabatago` isn't registered yet — check Apple Developer portal | | "Duplicate build number" | Build number already used — bump `CFBundleVersion` in `project.yml` and re-tag | | "Authentication failed" | API key was revoked, expired, or secret is misspelled — verify secrets in repository settings | diff --git a/docs/ci-cd-setup.md b/docs/ci-cd-setup.md new file mode 100644 index 0000000..66fe87d --- /dev/null +++ b/docs/ci-cd-setup.md @@ -0,0 +1,200 @@ +# CI/CD Setup — iPhone Deploy Workflow + +This guide covers setting up a **Gitea Actions** macOS runner to automatically build, test, and deploy **TabataGo** to a physical iPhone on every PR to `main`. + +## Prerequisites + +### Hardware +- **Mac** running macOS 15 (Sequoia) or later +- **Xcode 26+** installed (required for iOS 26.0 / watchOS 11.0 targets) +- **iPhone** (iOS 26+) with the Firebase App Tester app installed + +### Software +- [Gitea Actions Runner](https://docs.gitea.com/usage/actions/act-runner) installed and registered +- `brew` (Homebrew) installed +- `xcodegen` — `brew install xcodegen` (also installed automatically by the workflow) + +## 1. Register the macOS Runner + +```bash +# On the Mac: +./act_runner register \ + --instance https://gitea.1000co.fr \ + --token \ + --name "macos-runner" \ + --labels macos + +# Start the runner +./act_runner daemon +``` + +> **Important:** The runner must have the label `macos` because the workflow uses `runs-on: macos`. + +## 2. Configure Secrets + +Add these secrets in the Gitea repository: +`Settings → Actions → Secrets` + +| Secret Name | Description | How to Get | +|-------------|-------------|------------| +| `FIREBASE_APP_ID` | Firebase App ID (iOS app) | Firebase Console → Project Settings → General → App ID | +| `FIREBASE_SERVICE_ACCOUNT` | Base64-encoded Firebase service account JSON key | See [Firebase Setup](#6-firebase-app-distribution-setup) below | +| `GITEA_TOKEN` | Gitea API token with repo + pull request scope | `Gitea → Settings → Applications → Generate Token` | + +### Gitea Token Permissions +The token needs: +- `read:repository` — to read PR metadata +- `write:issue` — to post LGTM comments +- `write:pull_request` — to merge approved PRs + +## 3. Xcode Signing + +The workflow uses **automatic code signing**. Ensure: + +1. The Mac runner is signed into an Apple Developer account in Xcode: + ```bash + # Verify: + xcrun security find-identity -v -p codesigning + ``` + +2. The Apple ID used must be part of the team `2MJF39L8VY` (configured in `ExportOptions.plist`). + +3. For first-time setup, open Xcode on the runner Mac and sign in: + ``` + Xcode → Settings → Accounts → Add Apple ID + ``` + +## 4. Workflow Overview + +The workflow at `.gitea/workflows/pr-iphone-deploy.yml` triggers on PRs to `main`: + +``` +PR Opened / Updated + ↓ + Checkout + XcodeGen generate + ↓ + Resolve SPM packages + ↓ + Build + Archive IPA + ↓ + Upload to Firebase App Distribution + ↓ + Post "Ready to test" comment on PR + ↓ + Wait for LGTM → Auto-merge +``` + +## 5. Manual Test Run + +To test the workflow locally on the runner Mac: + +```bash +# Simulate the build: +cd tabatago-swift +xcodegen generate +xcodebuild build \ + -project TabataGo.xcodeproj \ + -target TabataGo \ + -sdk iphoneos \ + -destination "generic/platform=iOS" \ + -configuration Release \ + -allowProvisioningUpdates \ + -skipPackagePluginValidation \ + CODE_SIGN_STYLE=Automatic +``` + +## 6. Firebase App Distribution Setup + +### 6.1 Create a Firebase Project + +1. Go to [Firebase Console](https://console.firebase.google.com) +2. Click **Add project** (or select an existing one) +3. Follow the wizard to create the project (Google Analytics is optional) + +### 6.2 Enable App Distribution + +1. In the Firebase Console, open your project +2. Navigate to **App Distribution** in the left sidebar +3. Click **Get started** to enable the service + +### 6.3 Get the App ID + +1. Go to **Project Settings** (gear icon) → **General** +2. Scroll down to **Your apps** → find the iOS app +3. Copy the **App ID** (looks like `1:123456789012:ios:abc123def456`) + +### 6.4 Create a Service Account + +1. Go to **Project Settings** → **Service accounts** +2. Click **Create service account** (or use Firebase Admin SDK → Generate new private key) +3. Give it a name like `github-actions-deploy` +4. Assign the role: **Firebase App Distribution Admin** +5. Click **Generate new private key** → download the JSON file + +### 6.5 Encode the Service Account Key + +```bash +# Convert the JSON key to a base64 string (single line, no wrapping) +base64 -i firebase-key.json | tr -d '\n' +``` + +Copy the output — this is your `FIREBASE_SERVICE_ACCOUNT` secret value. + +### 6.6 Add Testers and Groups + +1. In Firebase Console, go to **App Distribution** → **Testers & Groups** +2. Click **Add group** → name it `millian-test` +3. Click **Add testers** → enter Millian's email +4. Add the tester to the `millian-test` group + +### 6.7 Install the Firebase App Tester on the iPhone + +1. Send an invite to Millian's iPhone from the Firebase Console +2. Millian accepts the invite and installs the **Firebase App Tester** app from the App Store +3. Open the app and sign in with the invited Google account +4. The app will now receive builds pushed from the CI workflow + +## Troubleshooting + +| Issue | Solution | +|-------|----------| +| "Code signing failed" | Sign into Xcode on the runner Mac, verify team membership | +| "No provisioning profile" | Run `-allowProvisioningUpdates` or open project in Xcode once | +| `xcodegen: command not found` | `brew install xcodegen` (workflow handles this) | +| Runner doesn't pick up job | Verify runner label is `macos` and runner is connected | +| Token permission errors | Ensure `GITEA_TOKEN` has `write:issue` and `write:pull_request` scopes | +| Firebase upload fails | Verify `FIREBASE_APP_ID` and `FIREBASE_SERVICE_ACCOUNT` secrets are set correctly | +| "App not found" in Firebase | Check that the iOS app is registered in Firebase with the correct bundle ID | +| Testers don't receive build | Verify tester is in the `millian-test` group and has accepted the invite | + +## Compilation Error Troubleshooting + +### xcodegen Clearing Signing Team + +After running `xcodegen generate`, the `.xcodeproj` may have a cleared signing team. Always re-check your team settings: + +```bash +cd tabatago-swift +xcodegen generate +# Then check that project.yml has the correct team ID in settings +``` + +### Complication Targets Missing Team ID + +Targets like **TabataGoWatchWidget** (watchOS complications) require an explicit team ID in `project.yml` settings. If you see signing errors for the widget target: + +1. Open `tabatago-swift/project.yml` +2. Find the `TabataGoWatchWidget` target section +3. Ensure it has an explicit `settings:` block with the team ID: + ```yaml + target: TabataGoWatchWidget + settings: + base: + DEVELOPMENT_TEAM: "2MJF39L8VY" + ``` + +### General Build Debugging + +- Run `xcodegen generate` before every build to ensure the project is in sync +- Check `xcodebuild` output for specific file/line errors +- Verify SPM packages resolve: `xcodebuild -resolvePackageDependencies` diff --git a/tabatago-swift/TabataGo.xcodeproj/project.pbxproj b/tabatago-swift/TabataGo.xcodeproj/project.pbxproj deleted file mode 100644 index f9869e6..0000000 --- a/tabatago-swift/TabataGo.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1374 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 77; - objects = { - -/* Begin PBXBuildFile section */ - 09285D4F326731E9A27827B2 /* MusicService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C9BB1EEE2291A9A23B5F3C /* MusicService.swift */; }; - 14578A06877E3D67A49650A9 /* AudioService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BAABCD29F20A3646B6A4036 /* AudioService.swift */; }; - 14EC768D950BC071AFBEFDF2 /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12715936CAA6BD90A7FBE9D7 /* MainTabView.swift */; }; - 18E74EE69364472DA7F0D9EC /* TabataGoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D558DAFE1AD94786AA674A4 /* TabataGoUITests.swift */; }; - 192F8CFFE1888005ABF339E8 /* WorkoutSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBFC7FC6A52DE9908EE4A6 /* WorkoutSession.swift */; }; - 1955D0D74D9B09D10705104C /* WorkoutProgram.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E64CFB210A549AC85F878D /* WorkoutProgram.swift */; }; - 20FD0BC9A6E01E8EA182E030 /* Supabase in Frameworks */ = {isa = PBXBuildFile; productRef = 2A66A0F120927A9EBC548828 /* Supabase */; }; - 22669D283A2B7C8D5F4FE19F /* ActivityRingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA8445E547E41DF784C3D2F /* ActivityRingView.swift */; }; - 29DA1C9905E244CDC316D5AA /* CompletionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44A6F4FB39AE902BCED1C2D5 /* CompletionView.swift */; }; - 2D5CE02211FB67CD2CFDAA11 /* SupabaseService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EDF0ED76A8476BF1F80EF8C /* SupabaseService.swift */; }; - 367B00BF0E8537F9BA15530F /* MusicTrack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C6156C6E0E1A543DAC87A90 /* MusicTrack.swift */; }; - 3A1A6EA59BD9CDEFBF22763F /* ProgramsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16C8FAFDECBFA2D9CF66505B /* ProgramsTab.swift */; }; - 3E2E78027B1973F72E05D8D2 /* PlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8206D4F904F61E5685DE369E /* PlayerViewModel.swift */; }; - 3F0F63E163BBA968C4CEFF81 /* TabataGoWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 484865AEFA8CCD26C4AE7F73 /* TabataGoWatch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3FAAAAC1576A7861AB833E39 /* ProfileTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B5DFE227FDB6400C8D7A4A4 /* ProfileTab.swift */; }; - 41096438BB67B60480460156 /* WatchL10n.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ACBDB7D81F575AC5370E82F /* WatchL10n.swift */; }; - 4371D8DD5F2638905606513A /* WatchActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8CA90001C65B27E3B7BE34 /* WatchActivityView.swift */; }; - 53FDC12EFCD8159045C105C0 /* HealthKitService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0499FCA348FF1A127C8E4FAE /* HealthKitService.swift */; }; - 556620C10FA0BC85E1BDE529 /* WatchIdleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 495E38AB3B412E296F8C3649 /* WatchIdleView.swift */; }; - 583A4EB0B1D20521D4A37D60 /* GlobalStatsCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66750D77B59FCF4F321B36E /* GlobalStatsCard.swift */; }; - 59B482DEBAA43EE5F24B883D /* HomeTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB04FA5E81BD1E52DEFB3AC2 /* HomeTab.swift */; }; - 5A25DA9A1B21F5EED15BA370 /* ProgramDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BFF744890571DE314540E16 /* ProgramDetailView.swift */; }; - 5A402D7E31059AB7107B625C /* MusicPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5505FBD6E001AE3AFD413ADA /* MusicPlayerViewModel.swift */; }; - 5B01ABC32F9B8FFD006E707D /* MusicActivityAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B01ABC22F9B8FFD006E707D /* MusicActivityAttributes.swift */; }; - 5B01ABC82F9B90AF006E707D /* ActivityKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B01ABC62F9B909E006E707D /* ActivityKit.framework */; }; - 5B10095F2FB7C4080033DE89 /* MockPrograms.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B10095E2FB7C4080033DE89 /* MockPrograms.swift */; }; - 5CE2F2210BEF17AC304F2AC2 /* HealthSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1DE8A4DAD846A879B8ED379 /* HealthSnapshot.swift */; }; - 60503F963221C7FCF719C493 /* ActivityTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84123E854DE0BF3E0D4F0912 /* ActivityTab.swift */; }; - 6060D95D485E4188EAABDDED /* WatchRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AEC37E6361DC4C7AE326139 /* WatchRootView.swift */; }; - 61BD8C313424F89F13FDE92E /* PurchaseViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8E005D62F3B3B80A2A53C2C /* PurchaseViewModel.swift */; }; - 66E87ABBDC5C3B36B3E932FB /* WatchConnectivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 802638FA5E5FDB5B278123AC /* WatchConnectivityManager.swift */; }; - 6C11E1F61F3ABADC7922C383 /* WeeklySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C8C8AEF5C3E8432CB07861 /* WeeklySection.swift */; }; - 70C2DAC704F628494A59EF56 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E5AA44513F793EA7FEBA00 /* Theme.swift */; }; - 70DEC8E97218C774A46F7CEA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CDFE1E10182972315386F9D7 /* Assets.xcassets */; }; - 725EBACF4CF7BC23D2C476AA /* TabataGoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09EB765FCE6A3EE95E86EB3 /* TabataGoApp.swift */; }; - 7B4E626E8A28525094C19B8D /* PurchaseService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A84A0F7F17713D5D0A679122 /* PurchaseService.swift */; }; - 80214BDEB93076416728E9BD /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = FE5B048B90231B158C0027EA /* PostHog */; }; - 8045D997CFE2447CBED7BF71 /* TabataGoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C5359B9E5850BE09484D2C /* TabataGoTests.swift */; }; - 850C700B060F46134C2D4569 /* WatchPlayerEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973741405B4155D15137B3C4 /* WatchPlayerEngine.swift */; }; - 86EF518650FBD42FF912DB58 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 5F5D3568A736B7A326874677 /* Localizable.xcstrings */; }; - 8C3B87A3ACCDE45862C33913 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE731C42C570A89F2C6F613 /* Strings.swift */; }; - 90728D374B15A38DD9A75E5B /* WatchPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC464C4D17B88E57FB5477C /* WatchPlayerView.swift */; }; - 93457B73C62C4BEA4329BD4C /* TabataGoWatchWidget.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 255972F9906563A0921C47C0 /* TabataGoWatchWidget.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 9633A730F910E47C28A288AC /* WatchConnectivityTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8425C668A3901B0F12DBFCD /* WatchConnectivityTypes.swift */; }; - 996E613C0A9906AB88D2AEB6 /* WorkoutCalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAEBB2380DAC8F565F556D41 /* WorkoutCalendarView.swift */; }; - 9F9695303EEC1516B1845417 /* TabataGoWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9006191EE89D06E6558786E3 /* TabataGoWatchApp.swift */; }; - AA17AD2E25DF408ECE100F99 /* PreviewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7482C05380DE017FF582C28B /* PreviewData.swift */; }; - AAA001AAA001AAA001AAA001 /* MusicActivityAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B01ABC22F9B8FFD006E707D /* MusicActivityAttributes.swift */; }; - AAA002AAA002AAA002AAA002 /* MusicLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB001BBB001BBB001BBB001 /* MusicLiveActivity.swift */; }; - AAA003AAA003AAA003AAA003 /* TabataGoWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB002BBB002BBB002BBB002 /* TabataGoWidgetBundle.swift */; }; - AAA004AAA004AAA004AAA004 /* TabataGoWidget.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = BBB004BBB004BBB004BBB004 /* TabataGoWidget.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - AAA005AAA005AAA005AAA005 /* WorkoutActivityAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB005BBB005BBB005BBB005 /* WorkoutActivityAttributes.swift */; }; - AAA006AAA006AAA006AAA006 /* WorkoutActivityAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB005BBB005BBB005BBB005 /* WorkoutActivityAttributes.swift */; }; - AAA007AAA007AAA007AAA007 /* WorkoutLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB006BBB006BBB006BBB006 /* WorkoutLiveActivity.swift */; }; - B4CFD4E752EF66F6535AD173 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 815C7C1CC22063B7E27F2F9B /* SettingsView.swift */; }; - B5591230E8B61A2B18F5DD87 /* WatchConnectivityTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8425C668A3901B0F12DBFCD /* WatchConnectivityTypes.swift */; }; - B60D023230A8BA995A812FC3 /* PhoneConnectivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25FD149C9626FEC155E8C72E /* PhoneConnectivityManager.swift */; }; - C2CB48B999939D3550A50936 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185636F13439162E23F874D3 /* Environment.swift */; }; - CA45F50F953886A372F22AA4 /* RevenueCat in Frameworks */ = {isa = PBXBuildFile; productRef = C18748562E7BDB56A11C0FB3 /* RevenueCat */; }; - CCCCEFD2D61ED1D7DDB9040C /* AnalyticsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C8A95404A7E4E05A1A7C34 /* AnalyticsService.swift */; }; - CDFA9A56DB6DA111B728FF48 /* BodyZoneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514301FBE811B1260720D151 /* BodyZoneView.swift */; }; - D03E8BFA9CC4400EC8718884 /* TabataGoSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DEACB2D18F636B35BB2C48 /* TabataGoSchema.swift */; }; - D422758C736D40CB0E9C4063 /* NowPlayingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B4E4F3DA1047ACD980F581 /* NowPlayingView.swift */; }; - D65673484CBB4DDA03C23225 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8242C26A4F51BE7AA779840 /* RootView.swift */; }; - D665638A80E06A7C42019782 /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E93E214AAB0E1CB61B89EC75 /* PlayerView.swift */; }; - D708AE54AD57CE932F9880DA /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C4C127C41584515D4EF95CB0 /* Localizable.xcstrings */; }; - DBFB6F75F59367A957B8F9B9 /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FE34000653EE789117CE9D9 /* UserProfile.swift */; }; - E21B9936D15D2111807AAAE9 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A422BCE1A702F8A10951FC /* OnboardingView.swift */; }; - E4ED0B8CABBD3502EA468F21 /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD1AF33C89F42294599C369A /* HomeViewModel.swift */; }; - EDAFF4CD2ACE82CC2C097B3C /* PaywallView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA21206AD91A5F95926EEA05 /* PaywallView.swift */; }; - EE6C591611D52C36ED5E03C6 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC19129CD3C493C8B2AEFA8 /* AppState.swift */; }; - F2E1D0C9B8A7F6E5D4C3B2A1 /* ZoneHighlightIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B2C3D4E5F6A7B8C9D0E1F2 /* ZoneHighlightIcon.swift */; }; - F80248DC6213339BC8F9C9A2 /* TabataGoComplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDA5D50FD057EF30BE7915F5 /* TabataGoComplication.swift */; }; - FD47EC832E23E0AF1D6FFE47 /* PolicyViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525C7E8EC6EF89E00D34672E /* PolicyViews.swift */; }; - FE14257B8CFFDC47C72AE079 /* HealthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63599808389B70FC2F6A43C3 /* HealthViewModel.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 199D4196A99EB5B38C309C5D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5D5CB9093007DF74EBDE3C98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3945C3998B4B66F30759718C; - remoteInfo = TabataGoWatch; - }; - D329F349FC6AF0E2D3C89FD3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5D5CB9093007DF74EBDE3C98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 90BAF2DB5D7456CD45975E26; - remoteInfo = TabataGoWatchWidget; - }; - DB62F40A2069EDBDA1F2AE98 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5D5CB9093007DF74EBDE3C98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 92991789C3A5B2A5FACF07A1; - remoteInfo = TabataGo; - }; - F48E1ED0786D563407445F4E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5D5CB9093007DF74EBDE3C98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 92991789C3A5B2A5FACF07A1; - remoteInfo = TabataGo; - }; - FFF001FFF001FFF001FFF001 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5D5CB9093007DF74EBDE3C98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EEE001EEE001EEE001EEE001; - remoteInfo = TabataGoWidget; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 76FE977236B376F31232D242 /* Embed Watch Content */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; - dstSubfolderSpec = 16; - files = ( - 3F0F63E163BBA968C4CEFF81 /* TabataGoWatch.app in Embed Watch Content */, - ); - name = "Embed Watch Content"; - runOnlyForDeploymentPostprocessing = 0; - }; - 97F207A5CEE6835FA097805C /* Embed Foundation Extensions */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 13; - files = ( - 93457B73C62C4BEA4329BD4C /* TabataGoWatchWidget.appex in Embed Foundation Extensions */, - ); - name = "Embed Foundation Extensions"; - runOnlyForDeploymentPostprocessing = 0; - }; - DDD002DDD002DDD002DDD002 /* Embed App Extensions */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 13; - files = ( - AAA004AAA004AAA004AAA004 /* TabataGoWidget.appex in Embed App Extensions */, - ); - name = "Embed App Extensions"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 01C5359B9E5850BE09484D2C /* TabataGoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabataGoTests.swift; sourceTree = ""; }; - 0499FCA348FF1A127C8E4FAE /* HealthKitService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthKitService.swift; sourceTree = ""; }; - 04C8A95404A7E4E05A1A7C34 /* AnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsService.swift; sourceTree = ""; }; - 12715936CAA6BD90A7FBE9D7 /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = ""; }; - 16C8FAFDECBFA2D9CF66505B /* ProgramsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgramsTab.swift; sourceTree = ""; }; - 185636F13439162E23F874D3 /* Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Environment.swift; sourceTree = ""; }; - 255972F9906563A0921C47C0 /* TabataGoWatchWidget.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TabataGoWatchWidget.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 25FD149C9626FEC155E8C72E /* PhoneConnectivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneConnectivityManager.swift; sourceTree = ""; }; - 28A422BCE1A702F8A10951FC /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; }; - 2C6156C6E0E1A543DAC87A90 /* MusicTrack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicTrack.swift; sourceTree = ""; }; - 2D8CA90001C65B27E3B7BE34 /* WatchActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchActivityView.swift; sourceTree = ""; }; - 31B4E4F3DA1047ACD980F581 /* NowPlayingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingView.swift; sourceTree = ""; }; - 33688B62F38435863620B90E /* TabataGo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TabataGo.entitlements; sourceTree = ""; }; - 44A6F4FB39AE902BCED1C2D5 /* CompletionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionView.swift; sourceTree = ""; }; - 484865AEFA8CCD26C4AE7F73 /* TabataGoWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TabataGoWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 495E38AB3B412E296F8C3649 /* WatchIdleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchIdleView.swift; sourceTree = ""; }; - 4EDF0ED76A8476BF1F80EF8C /* SupabaseService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupabaseService.swift; sourceTree = ""; }; - 514301FBE811B1260720D151 /* BodyZoneView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BodyZoneView.swift; sourceTree = ""; }; - 525C7E8EC6EF89E00D34672E /* PolicyViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolicyViews.swift; sourceTree = ""; }; - 5505FBD6E001AE3AFD413ADA /* MusicPlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicPlayerViewModel.swift; sourceTree = ""; }; - 58DEACB2D18F636B35BB2C48 /* TabataGoSchema.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabataGoSchema.swift; sourceTree = ""; }; - 5ACBDB7D81F575AC5370E82F /* WatchL10n.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchL10n.swift; sourceTree = ""; }; - 5B01ABC22F9B8FFD006E707D /* MusicActivityAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicActivityAttributes.swift; sourceTree = ""; }; - 5B01ABC62F9B909E006E707D /* ActivityKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ActivityKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.4.sdk/System/Library/Frameworks/ActivityKit.framework; sourceTree = DEVELOPER_DIR; }; - 5B10095E2FB7C4080033DE89 /* MockPrograms.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPrograms.swift; sourceTree = ""; }; - 5F5D3568A736B7A326874677 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; - 61E5AA44513F793EA7FEBA00 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; - 63599808389B70FC2F6A43C3 /* HealthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthViewModel.swift; sourceTree = ""; }; - 6BAABCD29F20A3646B6A4036 /* AudioService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioService.swift; sourceTree = ""; }; - 6BFF744890571DE314540E16 /* ProgramDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgramDetailView.swift; sourceTree = ""; }; - 6D558DAFE1AD94786AA674A4 /* TabataGoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabataGoUITests.swift; sourceTree = ""; }; - 7482C05380DE017FF582C28B /* PreviewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewData.swift; sourceTree = ""; }; - 75C8C8AEF5C3E8432CB07861 /* WeeklySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeeklySection.swift; sourceTree = ""; }; - 7FE34000653EE789117CE9D9 /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = ""; }; - 802638FA5E5FDB5B278123AC /* WatchConnectivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchConnectivityManager.swift; sourceTree = ""; }; - 815C7C1CC22063B7E27F2F9B /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; - 8206D4F904F61E5685DE369E /* PlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerViewModel.swift; sourceTree = ""; }; - 84123E854DE0BF3E0D4F0912 /* ActivityTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityTab.swift; sourceTree = ""; }; - 8AEC37E6361DC4C7AE326139 /* WatchRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchRootView.swift; sourceTree = ""; }; - 9006191EE89D06E6558786E3 /* TabataGoWatchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabataGoWatchApp.swift; sourceTree = ""; }; - 973741405B4155D15137B3C4 /* WatchPlayerEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchPlayerEngine.swift; sourceTree = ""; }; - 9B5DFE227FDB6400C8D7A4A4 /* ProfileTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTab.swift; sourceTree = ""; }; - 9CE731C42C570A89F2C6F613 /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = ""; }; - 9EC19129CD3C493C8B2AEFA8 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; - A1B2C3D4E5F6A7B8C9D0E1F2 /* ZoneHighlightIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoneHighlightIcon.swift; sourceTree = ""; }; - A7C07E8AF566483359CE2FEC /* TabataGoTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = TabataGoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - A84A0F7F17713D5D0A679122 /* PurchaseService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseService.swift; sourceTree = ""; }; - ACA8445E547E41DF784C3D2F /* ActivityRingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityRingView.swift; sourceTree = ""; }; - AD1AF33C89F42294599C369A /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModel.swift; sourceTree = ""; }; - B6E64CFB210A549AC85F878D /* WorkoutProgram.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutProgram.swift; sourceTree = ""; }; - B7EDA5BF7F25E3279A4B1A61 /* TabataGoUITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = TabataGoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - B8E005D62F3B3B80A2A53C2C /* PurchaseViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseViewModel.swift; sourceTree = ""; }; - BBB001BBB001BBB001BBB001 /* MusicLiveActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicLiveActivity.swift; sourceTree = ""; }; - BBB002BBB002BBB002BBB002 /* TabataGoWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabataGoWidgetBundle.swift; sourceTree = ""; }; - BBB003BBB003BBB003BBB003 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - BBB004BBB004BBB004BBB004 /* TabataGoWidget.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TabataGoWidget.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - BBB005BBB005BBB005BBB005 /* WorkoutActivityAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutActivityAttributes.swift; sourceTree = ""; }; - BBB006BBB006BBB006BBB006 /* WorkoutLiveActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutLiveActivity.swift; sourceTree = ""; }; - BBBBFC7FC6A52DE9908EE4A6 /* WorkoutSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutSession.swift; sourceTree = ""; }; - BD3DF875E3461305DADB554A /* Secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Secrets.xcconfig; sourceTree = ""; }; - C4C127C41584515D4EF95CB0 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; - C4C9BB1EEE2291A9A23B5F3C /* MusicService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicService.swift; sourceTree = ""; }; - CDA5D50FD057EF30BE7915F5 /* TabataGoComplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabataGoComplication.swift; sourceTree = ""; }; - CDFE1E10182972315386F9D7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - D09EB765FCE6A3EE95E86EB3 /* TabataGoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabataGoApp.swift; sourceTree = ""; }; - D168B973B16C94426A15766A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - D593D23B6A2F633DFA166D91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - D66750D77B59FCF4F321B36E /* GlobalStatsCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalStatsCard.swift; sourceTree = ""; }; - D8425C668A3901B0F12DBFCD /* WatchConnectivityTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WatchConnectivityTypes.swift; path = ../../TabataGo/Services/WatchConnectivityTypes.swift; sourceTree = ""; }; - D8A69F6B8DC5329436762B50 /* TabataGo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TabataGo.app; sourceTree = BUILT_PRODUCTS_DIR; }; - D983B6DEDE62A8F0E9E09E66 /* TabataGoWatch.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TabataGoWatch.entitlements; sourceTree = ""; }; - DA21206AD91A5F95926EEA05 /* PaywallView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallView.swift; sourceTree = ""; }; - DBC464C4D17B88E57FB5477C /* WatchPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchPlayerView.swift; sourceTree = ""; }; - E93E214AAB0E1CB61B89EC75 /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = ""; }; - F1DE8A4DAD846A879B8ED379 /* HealthSnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthSnapshot.swift; sourceTree = ""; }; - F8242C26A4F51BE7AA779840 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = ""; }; - FAEBB2380DAC8F565F556D41 /* WorkoutCalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutCalendarView.swift; sourceTree = ""; }; - FB04FA5E81BD1E52DEFB3AC2 /* HomeTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTab.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 078CF2C46E747BF4F8A74030 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 20FD0BC9A6E01E8EA182E030 /* Supabase in Frameworks */, - CA45F50F953886A372F22AA4 /* RevenueCat in Frameworks */, - 5B01ABC82F9B90AF006E707D /* ActivityKit.framework in Frameworks */, - 80214BDEB93076416728E9BD /* PostHog in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 0F5986A46D5DAC67217BB243 /* Services */ = { - isa = PBXGroup; - children = ( - 04C8A95404A7E4E05A1A7C34 /* AnalyticsService.swift */, - 6BAABCD29F20A3646B6A4036 /* AudioService.swift */, - 0499FCA348FF1A127C8E4FAE /* HealthKitService.swift */, - C4C9BB1EEE2291A9A23B5F3C /* MusicService.swift */, - 25FD149C9626FEC155E8C72E /* PhoneConnectivityManager.swift */, - A84A0F7F17713D5D0A679122 /* PurchaseService.swift */, - 4EDF0ED76A8476BF1F80EF8C /* SupabaseService.swift */, - ); - path = Services; - sourceTree = ""; - }; - 0FB4710828254C8629904415 /* Complications */ = { - isa = PBXGroup; - children = ( - D168B973B16C94426A15766A /* Info.plist */, - CDA5D50FD057EF30BE7915F5 /* TabataGoComplication.swift */, - ); - path = Complications; - sourceTree = ""; - }; - 162DB0E4C0FB82BCAC489598 /* Paywall */ = { - isa = PBXGroup; - children = ( - DA21206AD91A5F95926EEA05 /* PaywallView.swift */, - ); - path = Paywall; - sourceTree = ""; - }; - 1648643216F3497AF84AE1C3 /* Theme */ = { - isa = PBXGroup; - children = ( - 61E5AA44513F793EA7FEBA00 /* Theme.swift */, - ); - path = Theme; - sourceTree = ""; - }; - 1F1136D2B7FEBD67D18C7679 /* Resources */ = { - isa = PBXGroup; - children = ( - C4C127C41584515D4EF95CB0 /* Localizable.xcstrings */, - D983B6DEDE62A8F0E9E09E66 /* TabataGoWatch.entitlements */, - ); - path = Resources; - sourceTree = ""; - }; - 2CA2BFA0975A88FFA1C41C86 = { - isa = PBXGroup; - children = ( - 9070E6C405709C0B4D9623F9 /* Config */, - BD69946901F21DE2BEE0D8D9 /* TabataGo */, - DB98CF3F29FCFCDE4D54B1A8 /* TabataGoTests */, - 479C55D953F3D9AA136DE1BA /* TabataGoUITests */, - 66E9DD477B9F90EF36226076 /* TabataGoWatch */, - CCC001CCC001CCC001CCC001 /* TabataGoWidget */, - 5B01ABC52F9B909E006E707D /* Frameworks */, - F992A53DB1C399DCFE3C8BF2 /* Products */, - ); - sourceTree = ""; - }; - 3AD368BB11C8E02894C64345 /* Complete */ = { - isa = PBXGroup; - children = ( - 44A6F4FB39AE902BCED1C2D5 /* CompletionView.swift */, - ); - path = Complete; - sourceTree = ""; - }; - 3D6274962C5E19238FBFD579 /* App */ = { - isa = PBXGroup; - children = ( - 9006191EE89D06E6558786E3 /* TabataGoWatchApp.swift */, - ); - path = App; - sourceTree = ""; - }; - 479C55D953F3D9AA136DE1BA /* TabataGoUITests */ = { - isa = PBXGroup; - children = ( - 6D558DAFE1AD94786AA674A4 /* TabataGoUITests.swift */, - ); - path = TabataGoUITests; - sourceTree = ""; - }; - 4B4FB2F47AD5A34A21679372 /* Views */ = { - isa = PBXGroup; - children = ( - 2D8CA90001C65B27E3B7BE34 /* WatchActivityView.swift */, - 495E38AB3B412E296F8C3649 /* WatchIdleView.swift */, - DBC464C4D17B88E57FB5477C /* WatchPlayerView.swift */, - 8AEC37E6361DC4C7AE326139 /* WatchRootView.swift */, - ); - path = Views; - sourceTree = ""; - }; - 562818BD97AE83644CD2F695 /* Onboarding */ = { - isa = PBXGroup; - children = ( - 28A422BCE1A702F8A10951FC /* OnboardingView.swift */, - ); - path = Onboarding; - sourceTree = ""; - }; - 5B01ABC52F9B909E006E707D /* Frameworks */ = { - isa = PBXGroup; - children = ( - 5B01ABC62F9B909E006E707D /* ActivityKit.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 66E9DD477B9F90EF36226076 /* TabataGoWatch */ = { - isa = PBXGroup; - children = ( - 3D6274962C5E19238FBFD579 /* App */, - 0FB4710828254C8629904415 /* Complications */, - 1F1136D2B7FEBD67D18C7679 /* Resources */, - F514B75119B8194DB1791B95 /* Services */, - CE5E34713E694FAEED0F3480 /* Utilities */, - 4B4FB2F47AD5A34A21679372 /* Views */, - ); - path = TabataGoWatch; - sourceTree = ""; - }; - 850B47F4DD96E9CD7D6F412A /* Activity */ = { - isa = PBXGroup; - children = ( - ACA8445E547E41DF784C3D2F /* ActivityRingView.swift */, - D66750D77B59FCF4F321B36E /* GlobalStatsCard.swift */, - 75C8C8AEF5C3E8432CB07861 /* WeeklySection.swift */, - FAEBB2380DAC8F565F556D41 /* WorkoutCalendarView.swift */, - ); - path = Activity; - sourceTree = ""; - }; - 8B90DED418BDA3697748C37D /* Tabs */ = { - isa = PBXGroup; - children = ( - 850B47F4DD96E9CD7D6F412A /* Activity */, - 84123E854DE0BF3E0D4F0912 /* ActivityTab.swift */, - FB04FA5E81BD1E52DEFB3AC2 /* HomeTab.swift */, - 12715936CAA6BD90A7FBE9D7 /* MainTabView.swift */, - 9B5DFE227FDB6400C8D7A4A4 /* ProfileTab.swift */, - 16C8FAFDECBFA2D9CF66505B /* ProgramsTab.swift */, - ); - path = Tabs; - sourceTree = ""; - }; - 9070E6C405709C0B4D9623F9 /* Config */ = { - isa = PBXGroup; - children = ( - BD3DF875E3461305DADB554A /* Secrets.xcconfig */, - ); - path = Config; - sourceTree = ""; - }; - 98E39E3A8C6A422F8AED106C /* Health */ = { - isa = PBXGroup; - children = ( - ); - path = Health; - sourceTree = ""; - }; - A21FBA0964CB3FB318DE42E8 /* Views */ = { - isa = PBXGroup; - children = ( - 3AD368BB11C8E02894C64345 /* Complete */, - 98E39E3A8C6A422F8AED106C /* Health */, - 562818BD97AE83644CD2F695 /* Onboarding */, - 162DB0E4C0FB82BCAC489598 /* Paywall */, - A4BD547C912B1970BB98FC73 /* Player */, - C9F93E0937EB534BC24EF2FA /* Programs */, - EEAEB608A9FC8E5981B57A89 /* Settings */, - AA11BB22CC33DD44EE55FF66 /* Components */, - 8B90DED418BDA3697748C37D /* Tabs */, - ); - path = Views; - sourceTree = ""; - }; - A4BD547C912B1970BB98FC73 /* Player */ = { - isa = PBXGroup; - children = ( - 31B4E4F3DA1047ACD980F581 /* NowPlayingView.swift */, - E93E214AAB0E1CB61B89EC75 /* PlayerView.swift */, - ); - path = Player; - sourceTree = ""; - }; - A5772C2339F48ED5CF255A29 /* Utilities */ = { - isa = PBXGroup; - children = ( - 185636F13439162E23F874D3 /* Environment.swift */, - 9CE731C42C570A89F2C6F613 /* Strings.swift */, - ); - path = Utilities; - sourceTree = ""; - }; - AA11BB22CC33DD44EE55FF66 /* Components */ = { - isa = PBXGroup; - children = ( - A1B2C3D4E5F6A7B8C9D0E1F2 /* ZoneHighlightIcon.swift */, - ); - path = Components; - sourceTree = ""; - }; - BD69946901F21DE2BEE0D8D9 /* TabataGo */ = { - isa = PBXGroup; - children = ( - D72E5B5E6AA55AA4DD27D119 /* App */, - DC96ED5F68F75A02548ECD40 /* Models */, - DA785899F5E5947229C419DA /* Resources */, - 0F5986A46D5DAC67217BB243 /* Services */, - 1648643216F3497AF84AE1C3 /* Theme */, - A5772C2339F48ED5CF255A29 /* Utilities */, - CD710A86C04A7CE744A97D63 /* ViewModels */, - A21FBA0964CB3FB318DE42E8 /* Views */, - ); - path = TabataGo; - sourceTree = ""; - }; - C9F93E0937EB534BC24EF2FA /* Programs */ = { - isa = PBXGroup; - children = ( - 514301FBE811B1260720D151 /* BodyZoneView.swift */, - 6BFF744890571DE314540E16 /* ProgramDetailView.swift */, - ); - path = Programs; - sourceTree = ""; - }; - CCC001CCC001CCC001CCC001 /* TabataGoWidget */ = { - isa = PBXGroup; - children = ( - BBB003BBB003BBB003BBB003 /* Info.plist */, - BBB001BBB001BBB001BBB001 /* MusicLiveActivity.swift */, - BBB002BBB002BBB002BBB002 /* TabataGoWidgetBundle.swift */, - BBB006BBB006BBB006BBB006 /* WorkoutLiveActivity.swift */, - ); - path = TabataGoWidget; - sourceTree = ""; - }; - CD710A86C04A7CE744A97D63 /* ViewModels */ = { - isa = PBXGroup; - children = ( - 63599808389B70FC2F6A43C3 /* HealthViewModel.swift */, - AD1AF33C89F42294599C369A /* HomeViewModel.swift */, - 5505FBD6E001AE3AFD413ADA /* MusicPlayerViewModel.swift */, - 8206D4F904F61E5685DE369E /* PlayerViewModel.swift */, - B8E005D62F3B3B80A2A53C2C /* PurchaseViewModel.swift */, - ); - path = ViewModels; - sourceTree = ""; - }; - CE5E34713E694FAEED0F3480 /* Utilities */ = { - isa = PBXGroup; - children = ( - 5ACBDB7D81F575AC5370E82F /* WatchL10n.swift */, - ); - path = Utilities; - sourceTree = ""; - }; - D72E5B5E6AA55AA4DD27D119 /* App */ = { - isa = PBXGroup; - children = ( - 9EC19129CD3C493C8B2AEFA8 /* AppState.swift */, - F8242C26A4F51BE7AA779840 /* RootView.swift */, - D09EB765FCE6A3EE95E86EB3 /* TabataGoApp.swift */, - ); - path = App; - sourceTree = ""; - }; - DA785899F5E5947229C419DA /* Resources */ = { - isa = PBXGroup; - children = ( - CDFE1E10182972315386F9D7 /* Assets.xcassets */, - D593D23B6A2F633DFA166D91 /* Info.plist */, - 5F5D3568A736B7A326874677 /* Localizable.xcstrings */, - 33688B62F38435863620B90E /* TabataGo.entitlements */, - ); - path = Resources; - sourceTree = ""; - }; - DB98CF3F29FCFCDE4D54B1A8 /* TabataGoTests */ = { - isa = PBXGroup; - children = ( - 01C5359B9E5850BE09484D2C /* TabataGoTests.swift */, - ); - path = TabataGoTests; - sourceTree = ""; - }; - DC96ED5F68F75A02548ECD40 /* Models */ = { - isa = PBXGroup; - children = ( - 5B10095E2FB7C4080033DE89 /* MockPrograms.swift */, - F1DE8A4DAD846A879B8ED379 /* HealthSnapshot.swift */, - 2C6156C6E0E1A543DAC87A90 /* MusicTrack.swift */, - 7482C05380DE017FF582C28B /* PreviewData.swift */, - 58DEACB2D18F636B35BB2C48 /* TabataGoSchema.swift */, - 7FE34000653EE789117CE9D9 /* UserProfile.swift */, - B6E64CFB210A549AC85F878D /* WorkoutProgram.swift */, - BBBBFC7FC6A52DE9908EE4A6 /* WorkoutSession.swift */, - 5B01ABC22F9B8FFD006E707D /* MusicActivityAttributes.swift */, - BBB005BBB005BBB005BBB005 /* WorkoutActivityAttributes.swift */, - ); - path = Models; - sourceTree = ""; - }; - EEAEB608A9FC8E5981B57A89 /* Settings */ = { - isa = PBXGroup; - children = ( - 525C7E8EC6EF89E00D34672E /* PolicyViews.swift */, - 815C7C1CC22063B7E27F2F9B /* SettingsView.swift */, - ); - path = Settings; - sourceTree = ""; - }; - F514B75119B8194DB1791B95 /* Services */ = { - isa = PBXGroup; - children = ( - 802638FA5E5FDB5B278123AC /* WatchConnectivityManager.swift */, - D8425C668A3901B0F12DBFCD /* WatchConnectivityTypes.swift */, - 973741405B4155D15137B3C4 /* WatchPlayerEngine.swift */, - ); - path = Services; - sourceTree = ""; - }; - F992A53DB1C399DCFE3C8BF2 /* Products */ = { - isa = PBXGroup; - children = ( - D8A69F6B8DC5329436762B50 /* TabataGo.app */, - A7C07E8AF566483359CE2FEC /* TabataGoTests.xctest */, - B7EDA5BF7F25E3279A4B1A61 /* TabataGoUITests.xctest */, - 484865AEFA8CCD26C4AE7F73 /* TabataGoWatch.app */, - 255972F9906563A0921C47C0 /* TabataGoWatchWidget.appex */, - BBB004BBB004BBB004BBB004 /* TabataGoWidget.appex */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 3945C3998B4B66F30759718C /* TabataGoWatch */ = { - isa = PBXNativeTarget; - buildConfigurationList = E706A289AD3B8CCB1F3310BE /* Build configuration list for PBXNativeTarget "TabataGoWatch" */; - buildPhases = ( - 688CFA91471FB46E21B9EFB2 /* Sources */, - ABE017E9BF179D97311AB485 /* Resources */, - 97F207A5CEE6835FA097805C /* Embed Foundation Extensions */, - ); - buildRules = ( - ); - dependencies = ( - CAF3AD48883D2945C69905DF /* PBXTargetDependency */, - ); - name = TabataGoWatch; - packageProductDependencies = ( - ); - productName = TabataGoWatch; - productReference = 484865AEFA8CCD26C4AE7F73 /* TabataGoWatch.app */; - productType = "com.apple.product-type.application"; - }; - 90BAF2DB5D7456CD45975E26 /* TabataGoWatchWidget */ = { - isa = PBXNativeTarget; - buildConfigurationList = 569F5B8F2ACCAC8356B6D8A0 /* Build configuration list for PBXNativeTarget "TabataGoWatchWidget" */; - buildPhases = ( - 45E43A5DEF67C8A8869BB577 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = TabataGoWatchWidget; - packageProductDependencies = ( - ); - productName = TabataGoWatchWidget; - productReference = 255972F9906563A0921C47C0 /* TabataGoWatchWidget.appex */; - productType = "com.apple.product-type.app-extension"; - }; - 92991789C3A5B2A5FACF07A1 /* TabataGo */ = { - isa = PBXNativeTarget; - buildConfigurationList = D920067B8306F17FB19B987C /* Build configuration list for PBXNativeTarget "TabataGo" */; - buildPhases = ( - CD55FA03BDAE961D1DB600EC /* Sources */, - 3D4690E104FE866070533A03 /* Resources */, - 078CF2C46E747BF4F8A74030 /* Frameworks */, - 76FE977236B376F31232D242 /* Embed Watch Content */, - DDD002DDD002DDD002DDD002 /* Embed App Extensions */, - ); - buildRules = ( - ); - dependencies = ( - 08E32451A0A32FD65422174D /* PBXTargetDependency */, - GGG001GGG001GGG001GGG001 /* PBXTargetDependency */, - ); - name = TabataGo; - packageProductDependencies = ( - 2A66A0F120927A9EBC548828 /* Supabase */, - C18748562E7BDB56A11C0FB3 /* RevenueCat */, - FE5B048B90231B158C0027EA /* PostHog */, - ); - productName = TabataGo; - productReference = D8A69F6B8DC5329436762B50 /* TabataGo.app */; - productType = "com.apple.product-type.application"; - }; - D1E2CCCC7C9BD41029959883 /* TabataGoTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8588823708FAA81CCE59E4E2 /* Build configuration list for PBXNativeTarget "TabataGoTests" */; - buildPhases = ( - 58CC6E4A44750A943FC0D3D2 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - 4F860670537B1B4727317A1F /* PBXTargetDependency */, - ); - name = TabataGoTests; - packageProductDependencies = ( - ); - productName = TabataGoTests; - productReference = A7C07E8AF566483359CE2FEC /* TabataGoTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - D77CBB3569E06BDB4239862D /* TabataGoUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = B6509A4A480437475C2BD19E /* Build configuration list for PBXNativeTarget "TabataGoUITests" */; - buildPhases = ( - D7CD98EDC444042E53355A5B /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - A88A993C9D116DA16F65647B /* PBXTargetDependency */, - ); - name = TabataGoUITests; - packageProductDependencies = ( - ); - productName = TabataGoUITests; - productReference = B7EDA5BF7F25E3279A4B1A61 /* TabataGoUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; - EEE001EEE001EEE001EEE001 /* TabataGoWidget */ = { - isa = PBXNativeTarget; - buildConfigurationList = III001III001III001III001 /* Build configuration list for PBXNativeTarget "TabataGoWidget" */; - buildPhases = ( - DDD001DDD001DDD001DDD001 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = TabataGoWidget; - packageProductDependencies = ( - ); - productName = TabataGoWidget; - productReference = BBB004BBB004BBB004BBB004 /* TabataGoWidget.appex */; - productType = "com.apple.product-type.app-extension"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 5D5CB9093007DF74EBDE3C98 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 2600; - TargetAttributes = { - D77CBB3569E06BDB4239862D = { - TestTargetID = 92991789C3A5B2A5FACF07A1; - }; - }; - }; - buildConfigurationList = D511FD795A1B4393C6DBCCE8 /* Build configuration list for PBXProject "TabataGo" */; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - Base, - de, - en, - es, - fr, - ); - mainGroup = 2CA2BFA0975A88FFA1C41C86; - minimizedProjectReferenceProxies = 1; - packageReferences = ( - 2750E748A2B654070ACF7FDB /* XCRemoteSwiftPackageReference "posthog-ios" */, - C3900C1BDD31EBECA68AC321 /* XCRemoteSwiftPackageReference "purchases-ios" */, - B502009078E4064243CF221F /* XCRemoteSwiftPackageReference "supabase-swift" */, - ); - preferredProjectObjectVersion = 77; - productRefGroup = F992A53DB1C399DCFE3C8BF2 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 92991789C3A5B2A5FACF07A1 /* TabataGo */, - D1E2CCCC7C9BD41029959883 /* TabataGoTests */, - D77CBB3569E06BDB4239862D /* TabataGoUITests */, - 3945C3998B4B66F30759718C /* TabataGoWatch */, - 90BAF2DB5D7456CD45975E26 /* TabataGoWatchWidget */, - EEE001EEE001EEE001EEE001 /* TabataGoWidget */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 3D4690E104FE866070533A03 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 70DEC8E97218C774A46F7CEA /* Assets.xcassets in Resources */, - 86EF518650FBD42FF912DB58 /* Localizable.xcstrings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - ABE017E9BF179D97311AB485 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D708AE54AD57CE932F9880DA /* Localizable.xcstrings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 45E43A5DEF67C8A8869BB577 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F80248DC6213339BC8F9C9A2 /* TabataGoComplication.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 58CC6E4A44750A943FC0D3D2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8045D997CFE2447CBED7BF71 /* TabataGoTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 688CFA91471FB46E21B9EFB2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9F9695303EEC1516B1845417 /* TabataGoWatchApp.swift in Sources */, - 4371D8DD5F2638905606513A /* WatchActivityView.swift in Sources */, - 66E87ABBDC5C3B36B3E932FB /* WatchConnectivityManager.swift in Sources */, - B5591230E8B61A2B18F5DD87 /* WatchConnectivityTypes.swift in Sources */, - 556620C10FA0BC85E1BDE529 /* WatchIdleView.swift in Sources */, - 41096438BB67B60480460156 /* WatchL10n.swift in Sources */, - 850C700B060F46134C2D4569 /* WatchPlayerEngine.swift in Sources */, - 90728D374B15A38DD9A75E5B /* WatchPlayerView.swift in Sources */, - 6060D95D485E4188EAABDDED /* WatchRootView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - CD55FA03BDAE961D1DB600EC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 22669D283A2B7C8D5F4FE19F /* ActivityRingView.swift in Sources */, - 60503F963221C7FCF719C493 /* ActivityTab.swift in Sources */, - 5B10095F2FB7C4080033DE89 /* MockPrograms.swift in Sources */, - CCCCEFD2D61ED1D7DDB9040C /* AnalyticsService.swift in Sources */, - EE6C591611D52C36ED5E03C6 /* AppState.swift in Sources */, - 14578A06877E3D67A49650A9 /* AudioService.swift in Sources */, - CDFA9A56DB6DA111B728FF48 /* BodyZoneView.swift in Sources */, - 29DA1C9905E244CDC316D5AA /* CompletionView.swift in Sources */, - C2CB48B999939D3550A50936 /* Environment.swift in Sources */, - 583A4EB0B1D20521D4A37D60 /* GlobalStatsCard.swift in Sources */, - 53FDC12EFCD8159045C105C0 /* HealthKitService.swift in Sources */, - 5CE2F2210BEF17AC304F2AC2 /* HealthSnapshot.swift in Sources */, - FE14257B8CFFDC47C72AE079 /* HealthViewModel.swift in Sources */, - F2E1D0C9B8A7F6E5D4C3B2A1 /* ZoneHighlightIcon.swift in Sources */, - 59B482DEBAA43EE5F24B883D /* HomeTab.swift in Sources */, - E4ED0B8CABBD3502EA468F21 /* HomeViewModel.swift in Sources */, - 5B01ABC32F9B8FFD006E707D /* MusicActivityAttributes.swift in Sources */, - 14EC768D950BC071AFBEFDF2 /* MainTabView.swift in Sources */, - 5A402D7E31059AB7107B625C /* MusicPlayerViewModel.swift in Sources */, - 09285D4F326731E9A27827B2 /* MusicService.swift in Sources */, - 367B00BF0E8537F9BA15530F /* MusicTrack.swift in Sources */, - D422758C736D40CB0E9C4063 /* NowPlayingView.swift in Sources */, - E21B9936D15D2111807AAAE9 /* OnboardingView.swift in Sources */, - EDAFF4CD2ACE82CC2C097B3C /* PaywallView.swift in Sources */, - B60D023230A8BA995A812FC3 /* PhoneConnectivityManager.swift in Sources */, - D665638A80E06A7C42019782 /* PlayerView.swift in Sources */, - 3E2E78027B1973F72E05D8D2 /* PlayerViewModel.swift in Sources */, - FD47EC832E23E0AF1D6FFE47 /* PolicyViews.swift in Sources */, - AA17AD2E25DF408ECE100F99 /* PreviewData.swift in Sources */, - 3FAAAAC1576A7861AB833E39 /* ProfileTab.swift in Sources */, - 5A25DA9A1B21F5EED15BA370 /* ProgramDetailView.swift in Sources */, - 3A1A6EA59BD9CDEFBF22763F /* ProgramsTab.swift in Sources */, - 7B4E626E8A28525094C19B8D /* PurchaseService.swift in Sources */, - 61BD8C313424F89F13FDE92E /* PurchaseViewModel.swift in Sources */, - D65673484CBB4DDA03C23225 /* RootView.swift in Sources */, - B4CFD4E752EF66F6535AD173 /* SettingsView.swift in Sources */, - 8C3B87A3ACCDE45862C33913 /* Strings.swift in Sources */, - 2D5CE02211FB67CD2CFDAA11 /* SupabaseService.swift in Sources */, - 725EBACF4CF7BC23D2C476AA /* TabataGoApp.swift in Sources */, - D03E8BFA9CC4400EC8718884 /* TabataGoSchema.swift in Sources */, - 70C2DAC704F628494A59EF56 /* Theme.swift in Sources */, - DBFB6F75F59367A957B8F9B9 /* UserProfile.swift in Sources */, - 9633A730F910E47C28A288AC /* WatchConnectivityTypes.swift in Sources */, - 6C11E1F61F3ABADC7922C383 /* WeeklySection.swift in Sources */, - 996E613C0A9906AB88D2AEB6 /* WorkoutCalendarView.swift in Sources */, - 1955D0D74D9B09D10705104C /* WorkoutProgram.swift in Sources */, - 192F8CFFE1888005ABF339E8 /* WorkoutSession.swift in Sources */, - AAA005AAA005AAA005AAA005 /* WorkoutActivityAttributes.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D7CD98EDC444042E53355A5B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 18E74EE69364472DA7F0D9EC /* TabataGoUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DDD001DDD001DDD001DDD001 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AAA001AAA001AAA001AAA001 /* MusicActivityAttributes.swift in Sources */, - AAA002AAA002AAA002AAA002 /* MusicLiveActivity.swift in Sources */, - AAA003AAA003AAA003AAA003 /* TabataGoWidgetBundle.swift in Sources */, - AAA006AAA006AAA006AAA006 /* WorkoutActivityAttributes.swift in Sources */, - AAA007AAA007AAA007AAA007 /* WorkoutLiveActivity.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 08E32451A0A32FD65422174D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3945C3998B4B66F30759718C /* TabataGoWatch */; - targetProxy = 199D4196A99EB5B38C309C5D /* PBXContainerItemProxy */; - }; - 4F860670537B1B4727317A1F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 92991789C3A5B2A5FACF07A1 /* TabataGo */; - targetProxy = F48E1ED0786D563407445F4E /* PBXContainerItemProxy */; - }; - A88A993C9D116DA16F65647B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 92991789C3A5B2A5FACF07A1 /* TabataGo */; - targetProxy = DB62F40A2069EDBDA1F2AE98 /* PBXContainerItemProxy */; - }; - CAF3AD48883D2945C69905DF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 90BAF2DB5D7456CD45975E26 /* TabataGoWatchWidget */; - targetProxy = D329F349FC6AF0E2D3C89FD3 /* PBXContainerItemProxy */; - }; - GGG001GGG001GGG001GGG001 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EEE001EEE001EEE001EEE001 /* TabataGoWidget */; - targetProxy = FFF001FFF001FFF001FFF001 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 25D3B39EEB6D3E72B237E8F0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.uitests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = TabataGo; - }; - name = Release; - }; - 2917BEF34363D24B944CDBA1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.tests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TabataGo.app/TabataGo"; - }; - name = Release; - }; - 3DD4336C0CCAAAFD3B5F30DF /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEVELOPMENT_TEAM = 2MJF39L8VY; - INFOPLIST_FILE = TabataGoWatch/Complications/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.watchkitapp.widget; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Release; - }; - 44F45541FA6C5BFE5CCF517D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEVELOPMENT_TEAM = 2MJF39L8VY; - INFOPLIST_FILE = TabataGoWatch/Complications/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.watchkitapp.widget; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Debug; - }; - 5B2758E3710E78A54FCD6BD2 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BD3DF875E3461305DADB554A /* Secrets.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = TabataGo/Resources/TabataGo.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - DEVELOPMENT_TEAM = 2MJF39L8VY; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = TabataGo/Resources/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 637DF2A54A733BD3A292CA2D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - 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; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "DEBUG=1", - ); - 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; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_STRICT_CONCURRENCY = complete; - SWIFT_VERSION = 6.0; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Debug; - }; - 6C10FBA626E18FAABA747C30 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.tests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TabataGo.app/TabataGo"; - }; - name = Debug; - }; - 95D96CBB4EFBF492A95A92BA /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BD3DF875E3461305DADB554A /* Secrets.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = TabataGo/Resources/TabataGo.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - DEVELOPMENT_TEAM = 2MJF39L8VY; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = TabataGo/Resources/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - AC1DE840AE0DA9E76B9BB4EC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = TabataGoWatch/Resources/TabataGoWatch.entitlements; - DEVELOPMENT_TEAM = 2MJF39L8VY; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = TabataGoWatch/Resources/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.watchkitapp; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Debug; - }; - C771DA656A325C34900A1CA9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.uitests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = TabataGo; - }; - name = Debug; - }; - C7CBC011FEB78B687C73EE91 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = TabataGoWatch/Resources/TabataGoWatch.entitlements; - DEVELOPMENT_TEAM = 2MJF39L8VY; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = TabataGoWatch/Resources/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.watchkitapp; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Release; - }; - D464BA09CF5D5EE9E52925D8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - 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; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - 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; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_STRICT_CONCURRENCY = complete; - SWIFT_VERSION = 6.0; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Release; - }; - HHH001HHH001HHH001HHH001 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; - DEVELOPMENT_TEAM = 2MJF39L8VY; - INFOPLIST_FILE = TabataGoWidget/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.widget; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - HHH002HHH002HHH002HHH002 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; - DEVELOPMENT_TEAM = 2MJF39L8VY; - INFOPLIST_FILE = TabataGoWidget/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tabatago.app.widget; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 569F5B8F2ACCAC8356B6D8A0 /* Build configuration list for PBXNativeTarget "TabataGoWatchWidget" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 44F45541FA6C5BFE5CCF517D /* Debug */, - 3DD4336C0CCAAAFD3B5F30DF /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - 8588823708FAA81CCE59E4E2 /* Build configuration list for PBXNativeTarget "TabataGoTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6C10FBA626E18FAABA747C30 /* Debug */, - 2917BEF34363D24B944CDBA1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - B6509A4A480437475C2BD19E /* Build configuration list for PBXNativeTarget "TabataGoUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C771DA656A325C34900A1CA9 /* Debug */, - 25D3B39EEB6D3E72B237E8F0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - D511FD795A1B4393C6DBCCE8 /* Build configuration list for PBXProject "TabataGo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 637DF2A54A733BD3A292CA2D /* Debug */, - D464BA09CF5D5EE9E52925D8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - D920067B8306F17FB19B987C /* Build configuration list for PBXNativeTarget "TabataGo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 95D96CBB4EFBF492A95A92BA /* Debug */, - 5B2758E3710E78A54FCD6BD2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - E706A289AD3B8CCB1F3310BE /* Build configuration list for PBXNativeTarget "TabataGoWatch" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AC1DE840AE0DA9E76B9BB4EC /* Debug */, - C7CBC011FEB78B687C73EE91 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - III001III001III001III001 /* Build configuration list for PBXNativeTarget "TabataGoWidget" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - HHH001HHH001HHH001HHH001 /* Debug */, - HHH002HHH002HHH002HHH002 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 2750E748A2B654070ACF7FDB /* XCRemoteSwiftPackageReference "posthog-ios" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/PostHog/posthog-ios"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 3.0.0; - }; - }; - B502009078E4064243CF221F /* XCRemoteSwiftPackageReference "supabase-swift" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/supabase/supabase-swift"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 2.5.0; - }; - }; - C3900C1BDD31EBECA68AC321 /* XCRemoteSwiftPackageReference "purchases-ios" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/RevenueCat/purchases-ios"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 5.0.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 2A66A0F120927A9EBC548828 /* Supabase */ = { - isa = XCSwiftPackageProductDependency; - package = B502009078E4064243CF221F /* XCRemoteSwiftPackageReference "supabase-swift" */; - productName = Supabase; - }; - C18748562E7BDB56A11C0FB3 /* RevenueCat */ = { - isa = XCSwiftPackageProductDependency; - package = C3900C1BDD31EBECA68AC321 /* XCRemoteSwiftPackageReference "purchases-ios" */; - productName = RevenueCat; - }; - FE5B048B90231B158C0027EA /* PostHog */ = { - isa = XCSwiftPackageProductDependency; - package = 2750E748A2B654070ACF7FDB /* XCRemoteSwiftPackageReference "posthog-ios" */; - productName = PostHog; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = 5D5CB9093007DF74EBDE3C98 /* Project object */; -} diff --git a/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index a31781a..0000000 --- a/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,96 +0,0 @@ -{ - "originHash" : "42d1f35b4500c2779457daf99841f2333a14d9a2965835305d89fd95beda836e", - "pins" : [ - { - "identity" : "plcrashreporter", - "kind" : "remoteSourceControl", - "location" : "https://github.com/microsoft/plcrashreporter.git", - "state" : { - "revision" : "0254f941c646b1ed17b243654723d0f071e990d0", - "version" : "1.12.2" - } - }, - { - "identity" : "posthog-ios", - "kind" : "remoteSourceControl", - "location" : "https://github.com/PostHog/posthog-ios", - "state" : { - "revision" : "c3efdae383a5e7a5a88c34fd774e9d7dc915b9d4", - "version" : "3.55.0" - } - }, - { - "identity" : "purchases-ios", - "kind" : "remoteSourceControl", - "location" : "https://github.com/RevenueCat/purchases-ios", - "state" : { - "revision" : "bd63241b2258ea519020eb32a349db44fb44b119", - "version" : "5.68.0" - } - }, - { - "identity" : "supabase-swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/supabase/supabase-swift", - "state" : { - "revision" : "17261e93c60aa721e3c17312bfeb2ae6de3d6f8a", - "version" : "2.43.1" - } - }, - { - "identity" : "swift-asn1", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-asn1.git", - "state" : { - "revision" : "eb50cbd14606a9161cbc5d452f18797c90ef0bab", - "version" : "1.7.0" - } - }, - { - "identity" : "swift-clocks", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-clocks", - "state" : { - "revision" : "cc46202b53476d64e824e0b6612da09d84ffde8e", - "version" : "1.0.6" - } - }, - { - "identity" : "swift-concurrency-extras", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-concurrency-extras", - "state" : { - "revision" : "5a3825302b1a0d744183200915a47b508c828e6f", - "version" : "1.3.2" - } - }, - { - "identity" : "swift-crypto", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-crypto.git", - "state" : { - "revision" : "476538ccb827f2dd18efc5de754cc87d77127a47", - "version" : "4.4.0" - } - }, - { - "identity" : "swift-http-types", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-http-types.git", - "state" : { - "revision" : "45eb0224913ea070ec4fba17291b9e7ecf4749ca", - "version" : "1.5.1" - } - }, - { - "identity" : "xctest-dynamic-overlay", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", - "state" : { - "revision" : "dfd70507def84cb5fb821278448a262c6ff2bbad", - "version" : "1.9.0" - } - } - ], - "version" : 3 -} diff --git a/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/xcuserdata/20015659.xcuserdatad/UserInterfaceState.xcuserstate b/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/xcuserdata/20015659.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index b38bcd5..0000000 Binary files a/tabatago-swift/TabataGo.xcodeproj/project.xcworkspace/xcuserdata/20015659.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/tabatago-swift/TabataGo.xcodeproj/xcshareddata/xcschemes/TabataGo.xcscheme b/tabatago-swift/TabataGo.xcodeproj/xcshareddata/xcschemes/TabataGo.xcscheme deleted file mode 100644 index 980436d..0000000 --- a/tabatago-swift/TabataGo.xcodeproj/xcshareddata/xcschemes/TabataGo.xcscheme +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tabatago-swift/TabataGo.xcodeproj/xcshareddata/xcschemes/TabataGoTests.xcscheme b/tabatago-swift/TabataGo.xcodeproj/xcshareddata/xcschemes/TabataGoTests.xcscheme deleted file mode 100644 index f8c1078..0000000 --- a/tabatago-swift/TabataGo.xcodeproj/xcshareddata/xcschemes/TabataGoTests.xcscheme +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/tabatago-swift/TabataGo.xcodeproj/xcuserdata/20015659.xcuserdatad/xcschemes/xcschememanagement.plist b/tabatago-swift/TabataGo.xcodeproj/xcuserdata/20015659.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 6ae3595..0000000 --- a/tabatago-swift/TabataGo.xcodeproj/xcuserdata/20015659.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - SchemeUserState - - TabataGo.xcscheme_^#shared#^_ - - orderHint - 1 - - TabataGoTests.xcscheme_^#shared#^_ - - orderHint - 0 - - TabataGoUITests.xcscheme_^#shared#^_ - - orderHint - 2 - - TabataGoWatch.xcscheme_^#shared#^_ - - orderHint - 0 - - TabataGoWatchWidget.xcscheme_^#shared#^_ - - orderHint - 1 - - TabataGoWidget.xcscheme_^#shared#^_ - - orderHint - 2 - - - SuppressBuildableAutocreation - - 3945C3998B4B66F30759718C - - primary - - - 90BAF2DB5D7456CD45975E26 - - primary - - - 92991789C3A5B2A5FACF07A1 - - primary - - - D1E2CCCC7C9BD41029959883 - - primary - - - - - diff --git a/tabatago-swift/TabataGo/Services/AnalyticsService.swift b/tabatago-swift/TabataGo/Services/AnalyticsService.swift index bd04448..e7259d8 100644 --- a/tabatago-swift/TabataGo/Services/AnalyticsService.swift +++ b/tabatago-swift/TabataGo/Services/AnalyticsService.swift @@ -1,30 +1,38 @@ import Foundation +#if canImport(PostHog) import PostHog +#endif /// PostHog analytics — mirrors the event taxonomy from the Expo app. final class AnalyticsService: @unchecked Sendable { static let shared = AnalyticsService() +#if canImport(PostHog) private let apiKey: String = Bundle.main.infoDictionary?["POSTHOG_API_KEY"] as? String ?? "" private let host = "https://eu.posthog.com" +#endif private init() {} func initialize() { +#if canImport(PostHog) guard !apiKey.isEmpty else { return } let config = PostHogConfig(apiKey: apiKey, host: host) config.captureApplicationLifecycleEvents = true config.captureScreenViews = false // manual tracking PostHogSDK.shared.setup(config) +#endif } // ─── Screens ──────────────────────────────────────────────── func screen(_ name: String, properties: [String: Any] = [:]) { +#if canImport(PostHog) PostHogSDK.shared.screen(name, properties: properties) +#endif } // ─── Onboarding ───────────────────────────────────────────── @@ -100,6 +108,8 @@ final class AnalyticsService: @unchecked Sendable { // ─── Private ───────────────────────────────────────────────── private func capture(_ event: String, properties: [String: Any] = [:]) { +#if canImport(PostHog) PostHogSDK.shared.capture(event, properties: properties.isEmpty ? nil : properties) +#endif } } diff --git a/tabatago-swift/TabataGoWatch/Complications/TabataGoComplication.swift b/tabatago-swift/TabataGoWatch/Complications/TabataGoComplication.swift index a07d964..b3d557c 100644 --- a/tabatago-swift/TabataGoWatch/Complications/TabataGoComplication.swift +++ b/tabatago-swift/TabataGoWatch/Complications/TabataGoComplication.swift @@ -13,7 +13,7 @@ struct TabataEntry: TimelineEntry { struct TabataProvider: TimelineProvider { - private let sharedDefaults = UserDefaults(suiteName: "group.com.tabatago.app") + private let sharedDefaults = UserDefaults(suiteName: "group.fr.millianlmx.tabatago") func placeholder(in context: Context) -> TabataEntry { TabataEntry(date: Date(), streak: 7, lastWorkoutLabel: "Today") @@ -98,6 +98,8 @@ struct RectangularComplicationView: View { } /// `.accessoryCorner` — tiny bolt + streak digit in the corner +#if canImport(WatchKit) +@available(watchOS 10.0, *) struct CornerComplicationView: View { let entry: TabataEntry @@ -111,6 +113,7 @@ struct CornerComplicationView: View { .widgetLabel(String(format: String(localized: LocalizedStringResource("watch.complication.dayStreakFmt")), entry.streak)) } } +#endif // ─── Widget definition ──────────────────────────────────────────────────────── @@ -124,11 +127,11 @@ struct TabataGoComplication: Widget { } .configurationDisplayName("TabataGo") .description(String(localized: LocalizedStringResource("watch.complication.description"))) - .supportedFamilies([ - .accessoryCircular, - .accessoryRectangular, - .accessoryCorner - ]) +#if canImport(WatchKit) + .supportedFamilies([.accessoryCircular, .accessoryRectangular, .accessoryCorner]) +#else + .supportedFamilies([.accessoryCircular, .accessoryRectangular]) +#endif } } @@ -142,8 +145,10 @@ struct TabataComplicationEntryView: View { CircularComplicationView(entry: entry) case .accessoryRectangular: RectangularComplicationView(entry: entry) +#if canImport(WatchKit) case .accessoryCorner: CornerComplicationView(entry: entry) +#endif default: CircularComplicationView(entry: entry) } @@ -163,3 +168,12 @@ struct TabataComplicationEntryView: View { } timeline: { TabataEntry(date: .now, streak: 7, lastWorkoutLabel: "Today") } + +#if canImport(WatchKit) +@available(watchOS 10.0, *) +#Preview("Corner", as: .accessoryCorner) { + TabataGoComplication() +} timeline: { + TabataEntry(date: .now, streak: 7, lastWorkoutLabel: "Today") +} +#endif diff --git a/tabatago-swift/TabataGoWatch/Resources/Info.plist b/tabatago-swift/TabataGoWatch/Resources/Info.plist index 66947f8..0eed266 100644 --- a/tabatago-swift/TabataGoWatch/Resources/Info.plist +++ b/tabatago-swift/TabataGoWatch/Resources/Info.plist @@ -27,6 +27,6 @@ WKApplication WKCompanionAppBundleIdentifier - com.tabatago.app + fr.millianlmx.tabatago diff --git a/tabatago-swift/TabataGoWatch/Resources/TabataGoWatch.entitlements b/tabatago-swift/TabataGoWatch/Resources/TabataGoWatch.entitlements index f2ea579..c1f3cd2 100644 --- a/tabatago-swift/TabataGoWatch/Resources/TabataGoWatch.entitlements +++ b/tabatago-swift/TabataGoWatch/Resources/TabataGoWatch.entitlements @@ -6,7 +6,7 @@ com.apple.security.application-groups - group.com.tabatago.app + group.fr.millianlmx.tabatago diff --git a/tabatago-swift/TabataGoWatch/Views/WatchActivityView.swift b/tabatago-swift/TabataGoWatch/Views/WatchActivityView.swift index 67b0cb7..1f3cfaf 100644 --- a/tabatago-swift/TabataGoWatch/Views/WatchActivityView.swift +++ b/tabatago-swift/TabataGoWatch/Views/WatchActivityView.swift @@ -13,7 +13,7 @@ struct WatchActivityView: View { @State private var isLoading = true private let healthStore = HKHealthStore() - private let sharedDefaults = UserDefaults(suiteName: "group.com.tabatago.app") + private let sharedDefaults = UserDefaults(suiteName: "group.fr.millianlmx.tabatago") var body: some View { ScrollView { diff --git a/tabatago-swift/project.yml b/tabatago-swift/project.yml index ef06f42..7f7d5db 100644 --- a/tabatago-swift/project.yml +++ b/tabatago-swift/project.yml @@ -1,7 +1,7 @@ name: TabataGo options: - bundleIdPrefix: com.tabatago + bundleIdPrefix: fr.millianlmx.tabatago deploymentTarget: iOS: "26.0" watchOS: "11.0" @@ -15,7 +15,11 @@ settings: SWIFT_VERSION: "6.0" IPHONEOS_DEPLOYMENT_TARGET: "26.0" SWIFT_STRICT_CONCURRENCY: complete + SWIFT_EMIT_MODULE_FOR_EXPLICIT_BUILD: NO + GCC_TREAT_WARNINGS_AS_ERRORS: NO + SWIFT_TREAT_WARNINGS_AS_ERRORS: NO DEBUG_INFORMATION_FORMAT: dwarf-with-dsym + DEVELOPMENT_TEAM: "2MJF39L8VY" packages: Supabase: @@ -24,9 +28,6 @@ packages: RevenueCat: url: https://github.com/RevenueCat/purchases-ios from: "5.0.0" - PostHog: - url: https://github.com/PostHog/posthog-ios - from: "3.0.0" targets: TabataGo: @@ -66,19 +67,18 @@ targets: com.apple.developer.healthkit.access: - health-records com.apple.security.application-groups: - - group.com.tabatago.app + - group.fr.millianlmx.tabatago dependencies: - package: Supabase product: Supabase - package: RevenueCat product: RevenueCat - - package: PostHog - product: PostHog + - target: TabataGoWatch embed: true settings: base: - PRODUCT_BUNDLE_IDENTIFIER: com.tabatago.app + PRODUCT_BUNDLE_IDENTIFIER: fr.millianlmx.tabatago INFOPLIST_FILE: TabataGo/Resources/Info.plist CODE_SIGN_ENTITLEMENTS: TabataGo/Resources/TabataGo.entitlements ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon @@ -112,7 +112,7 @@ targets: CFBundleShortVersionString: "1.0" CFBundleVersion: "2" WKApplication: true - WKCompanionAppBundleIdentifier: com.tabatago.app + WKCompanionAppBundleIdentifier: fr.millianlmx.tabatago NSHealthShareUsageDescription: "TabataGo reads your heart rate and calories during workouts." NSHealthUpdateUsageDescription: "TabataGo saves workout data to Apple Health directly from your Watch." entitlements: @@ -120,13 +120,13 @@ targets: properties: com.apple.developer.healthkit: true com.apple.security.application-groups: - - group.com.tabatago.app + - group.fr.millianlmx.tabatago dependencies: - target: TabataGoWatchWidget embed: true settings: base: - PRODUCT_BUNDLE_IDENTIFIER: com.tabatago.app.watchkitapp + PRODUCT_BUNDLE_IDENTIFIER: fr.millianlmx.tabatago.watchkitapp INFOPLIST_FILE: TabataGoWatch/Resources/Info.plist CODE_SIGN_ENTITLEMENTS: TabataGoWatch/Resources/TabataGoWatch.entitlements ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon @@ -152,7 +152,7 @@ targets: NSExtensionPointIdentifier: com.apple.widgetkit-extension settings: base: - PRODUCT_BUNDLE_IDENTIFIER: com.tabatago.app.watchkitapp.widget + PRODUCT_BUNDLE_IDENTIFIER: fr.millianlmx.tabatago.watchkitapp.widget TARGETED_DEVICE_FAMILY: "4" WATCHOS_DEPLOYMENT_TARGET: "11.0" @@ -166,7 +166,7 @@ targets: - target: TabataGo settings: base: - PRODUCT_BUNDLE_IDENTIFIER: com.tabatago.app.tests + PRODUCT_BUNDLE_IDENTIFIER: fr.millianlmx.tabatago.tests TabataGoUITests: type: bundle.ui-testing @@ -178,4 +178,14 @@ targets: - target: TabataGo settings: base: - PRODUCT_BUNDLE_IDENTIFIER: com.tabatago.app.uitests + PRODUCT_BUNDLE_IDENTIFIER: fr.millianlmx.tabatago.uitests + +schemes: + TabataGo: + build: + targets: + TabataGo: all + run: + config: Debug + archive: + config: Release