A workout execution app for iPhone and Apple Watch.
Follow your training plan, complete sets from your wrist, and keep the next action visible without repeatedly unlocking your phone.
Most lifting apps focus on recording what happened after the fact. LiftState is designed around executing a predefined workout in the moment:
- The Apple Watch acts as the primary workout controller.
- The iPhone Lock Screen shows the current exercise, set, prescription, next action, and timer through a Live Activity.
- Completing a set advances the workout automatically.
- Supersets are first-class blocks, so rest begins only after every exercise in a round is complete.
- Workout history is produced as a natural result of following the plan.
- Create multiple workout plans and named workout days.
- Build straight-set, superset, and timed-exercise blocks.
- Configure sets, reps, weight, rest periods, timed holds, and per-side exercises.
- Add, edit, and safely delete workout content.
- Start a workout from its day screen or by long-pressing a day on the plans screen.
- See the current exercise, round, weight, reps, and next action at a glance.
- Complete a set with one tap.
- Run rest and timed-exercise countdowns using absolute end times.
- Skip rest, add 30 seconds, pause, and view workout progress.
- Receive a haptic when a timer finishes.
- Follow the active workout in a large, gym-friendly interface.
- Adjust today's weight quickly and tag an exercise to go down, stay, or go up next time.
- Keep workout state visible in a Lock Screen and Dynamic Island Live Activity.
- Complete sets, skip rest, or add time directly from the Lock Screen Live Activity.
- Resume an interrupted workout after relaunching the app.
- Review dated workout history, completed sets, volume, and previous performance.
- Export complete set-by-set history as CSV for spreadsheets and custom analysis.
- macOS with Xcode 26 or newer
- iOS 17 or newer
- watchOS 10 or newer for the Watch app
- An Apple Developer account and a physical iPhone for on-device installation
- A paired Apple Watch or paired iPhone/Watch simulators to test device communication
- Clone the repository and open
LiftState.xcodeprojin Xcode. - Select the LiftState scheme.
- Choose an iPhone simulator from the run-destination menu.
- Press Run (
⌘R).
For the Watch experience, create or select a paired iPhone and Apple Watch simulator. Run the iPhone app, start a workout, and then open LiftState on the paired Watch simulator.
The app includes a sample Push/Pull/Legs plan so the workout flow is ready to try immediately.
Before running on your own iPhone and Watch:
- Select your Apple Developer team for the LiftState, LiftStateWatch, LiftStateWidgets, and test targets.
- Replace the included
com.travismatthews.LiftStateidentifiers with identifiers owned by your team. - Keep the Watch and widget identifiers nested beneath the main app identifier.
- Set the Watch target's
WKCompanionAppBundleIdentifierto the exact bundle identifier of the iPhone app. - Allow Xcode to manage signing, connect your iPhone, and press Run.
Apps installed directly from Xcode require Developer Mode on the device. Distribution without Developer Mode requires a signed TestFlight or App Store build.
LiftStateApp/ iPhone SwiftUI interface
LiftStateWatch/ watchOS workout controller
LiftStateWidgets/ Live Activity and Dynamic Island UI
Shared/
Engine/ Deterministic workout state machine
Models/ Codable plans, sessions, and activity state
Services/ Persistence, connectivity, and Live Activities
LiftStateTests/ Workout sequencing and timer tests
WorkoutSession is the source of truth for workout progression. Views issue commands such as complete, skip, or add time; they do not decide which exercise comes next.
Active sessions are represented by a Codable SessionSnapshot, which is also the persistence and iPhone–Watch synchronization boundary. Timers store an absolute timerEndDate instead of a decrementing counter, keeping them accurate across screen dimming, suspension, connectivity delays, and relaunches.
Plans and history use a local-first atomic JSON store. HealthKit is not used as the primary workout-plan database.
Build the complete simulator app:
xcodebuild \
-project LiftState.xcodeproj \
-scheme LiftState \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro Max' \
CODE_SIGNING_ALLOWED=NO \
buildRun the test suite:
xcodebuild \
-project LiftState.xcodeproj \
-scheme LiftState \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro Max' \
testLiftState is an active MVP. The core plan editor, workout engine, Watch controller, local history, persistence, connectivity, timers, and Live Activity are implemented.
Not yet complete:
- Writing completed workouts to HealthKit
- A watch-face complication
- Cloud synchronization and backup
- Circuits, substitutions, and automatic progression
- Advanced charts and analytics
- App Store/TestFlight distribution configuration
Issues and pull requests are welcome. For changes to workout progression, add or update state-machine tests alongside the implementation. Please keep workout sequencing inside WorkoutSession rather than adding navigation decisions to views.
If you plan to publish a fork, use your own bundle identifiers and Apple Developer signing team.