Conversation
Add inline App Intents (iOS 16+) for Siri integration: - PaceToSpeedIntent: converts mm:ss pace to MPH/KPH - SpeedToPaceIntent: converts speed value to mm:ss pace - SpeedUnitEntity: AppEnum for MPH/KPH selection - RunPaceShortcuts: AppShortcutsProvider with Siri phrases Uses existing ConversionEngine for all conversion logic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add dedup check in ConversionHistory.add() to skip identical consecutive saves - Trigger recordCurrentConversion() in switchDirection() and switchUnit() - Add onChange listener for keyboard dismiss to capture intent to navigate away - Relax input validation from count>1 to non-empty to allow single-digit speeds
Add onChange listener to detect keyboard focus loss and trigger save, capturing intent to navigate away or interact with controls.
There was a problem hiding this comment.
Pull request overview
Adds new race-calculation tools (finish-time, even splits, negative splits), favorites + history persistence, haptic feedback triggers, and App Intents/Shortcuts support, while introducing a watchOS target and consolidating navigation into a single menu.
Changes:
- Add Race Calculator (finish time / required pace), Even Splits, and Negative Splits views backed by a new
RaceCalculatormodel. - Add Favorites + History persistence (
FavoritesStore,ConversionHistory) and wire them into the main converter UI. - Add App Intents + Shortcuts for pace/speed conversion and expand test coverage with new regression/unit tests.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pace-to-mphTests/RaceCalculatorTests.swift | Adds unit tests for RaceCalculator and negative split behavior. |
| pace-to-mphTests/IntentConversionRegressionTests.swift | Adds regression tests for AppIntents conversion outputs + dialog text. |
| pace-to-mphTests/FavoritesStoreTests.swift | Adds persistence/store behavior tests for favorites. |
| pace-to-mph/ViewModels/ConverterViewModel.swift | Adds conversion history tracking and records conversions on direction/unit changes. |
| pace-to-mph/SplitCalculatorView.swift | New Even Splits calculator UI. |
| pace-to-mph/RaceTimeView.swift | New finish time calculator UI. |
| pace-to-mph/NegativeSplitView.swift | New negative splits calculator UI + splits list rendering. |
| pace-to-mph/Models/RaceCalculator.swift | New model for duration parsing/formatting, pace/time calculations, negative splits. |
| pace-to-mph/Models/FavoritesStore.swift | New favorites persistence store using UserDefaults. |
| pace-to-mph/Models/ConversionHistory.swift | New conversion history persistence store using UserDefaults. |
| pace-to-mph/Models/ConversionEngine.swift | Marks conversion engine nonisolated (actor-isolation opt-out) while keeping conversion logic. |
| pace-to-mph/Intents/SpeedUnitEntity.swift | Adds AppEnum wrapper for speed units for intents. |
| pace-to-mph/Intents/SpeedToPaceIntent.swift | Adds Speed→Pace AppIntent. |
| pace-to-mph/Intents/RunPaceShortcuts.swift | Registers two app shortcuts (pace→speed, speed→pace). |
| pace-to-mph/Intents/PaceToSpeedIntent.swift | Adds Pace→Speed AppIntent. |
| pace-to-mph/HistoryView.swift | New history UI with “clear” + favorite toggle per record. |
| pace-to-mph/FavoritesView.swift | New favorites UI with “clear” + remove actions. |
| pace-to-mph/ContentView.swift | Consolidates navigation into menu; wires favorites/history; adds haptic feedback on result changes. |
| pace-to-mph.xcodeproj/xcuserdata/saad.xcuserdatad/xcschemes/xcschememanagement.plist | Updates scheme ordering in user-specific Xcode data. |
| pace-to-mph.xcodeproj/project.pbxproj | Adds watchOS app target + build settings. |
| AGENTS.md | Adds contributor guidelines for committing and post-review workflow. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- precompute cumulative seconds in NegativeSplitView to avoid O(n²) reduce - compute isFav once in ContentView star button to avoid duplicate work - migrate FavoritesStoreTests to isolated UserDefaults suites via makeStore helper
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ing remainder When difference > 0, add remainder to splitTimes[0] (slowest split) instead of splitTimes[last] (fastest). Adding to the last split can make it equal to or slower than the prior split when dropSeconds is small. Regression: negativeSplitsRoundingPreservesStrictlyDecreasingOrder (202s/6mi/1s-drop produced splits[4]==splits[5]==32)
… splits with negative differences
Move ConversionEngine and RaceCalculator to Shared/ so both iOS and watch targets use them directly. Remove SharedConversionMath wrapper and watch-local WatchSpeedUnit/WatchRaceDistance duplicates. Restore inline implementations, add Distance helpers (shortLabel, distance(unit:), standardCases) for watch usage.
…ime warnings - Custom PaceInputRow with crown input eliminates ScrollView contentOffset warning - Single digitalCrownRotation binding avoids Crown Sequencer warning - UnitToggle/DistanceSelector custom button bars replace incompatible Picker styles - Glass card styling on result displays
Add bounds check for seconds component to match parseDuration validation. Add regression tests for invalid seconds inputs.
…n NegativeSplitView
Summary
Testing
pace-to-mphTestsandpace-to-mphUITests