Skip to content

Latest commit

 

History

History
104 lines (77 loc) · 4.85 KB

File metadata and controls

104 lines (77 loc) · 4.85 KB

Building the mobile app (iOS / Android)

openGym ships in two flavors from the same codebase:

Self-hosted (this repo's default) Mobile app (VITE_MOBILE=1)
Runs in any browser, against your own server natively on iPhone / Android (Capacitor shell)
Accounts passkey sign-in, one profile per person none — the phone is the account
Data synced to your server, readable on desktop stays on the device (file in the app's private storage)
Reminders Web Push from your server native local notifications, no server involved
Exercise media served by your server (img/, gif/) loaded from the jsDelivr CDN

The mobile flavor never talks to a backend: no sign-in screen, no sync, no telemetry. State is mirrored from localStorage into opengym-state.json in the app's private data directory on every change (iOS is allowed to evict WebView storage under pressure — the file mirror is the durable copy and is restored on launch). Backups go out through the OS share sheet instead of a browser download.

Prerequisites

  • Node 20+
  • Android: Android Studio (bundles the SDK). Java 21 for Gradle.
  • iOS: a Mac with Xcode 15+ and CocoaPods (brew install cocoapods). A free Apple ID is enough to run the app on your own iPhone (see below); paid membership is only needed for App Store distribution, which openGym doesn't do.

Build & run

cd frontend
npm install
npm run build:mobile        # VITE_MOBILE build + `cap sync` into android/ and ios/

npx cap open android        # opens Android Studio → run on emulator or device
npx cap open ios            # opens Xcode (Mac only) → set your signing team, then run

npm run build:mobile bakes the CDN media base into the bundle and copies the web build into both native projects — re-run it after every web-code change before building natively.

Heads-up: after build:mobile, frontend/dist contains the mobile bundle. Run a plain npm run build again before deploying dist to a server.

App icons & splash screens

frontend/resources/icon.svg is the 1024×1024 source (the app's dumbbell glyph on the app background). Generate all platform assets from it on a machine with the tooling:

cd frontend
npx @capacitor/assets generate --iconBackgroundColor '#0c0e12' --splashBackgroundColor '#0c0e12'

(If the generator won't take the SVG directly, export it to resources/icon.png at 1024×1024 first — any image tool can do it.)

Distribution — deliberately no app stores

openGym's mobile app is not on the Play Store or App Store, and that's a choice: no store accounts, no store rules, no yearly fees between you and an open-source app.

Android — sideload the APK

The official signed APK is at opengym.duarte-santos.ch. Android asks you to allow installs from the browser the first time — that's standard for any app outside the Play Store.

To build and sign your own:

cd frontend && npm run build:mobile
cd android && ./gradlew assembleRelease            # → app/build/outputs/apk/release/app-release-unsigned.apk

# one-time: create a keystore. KEEP IT — updates must be signed with the same key,
# or Android refuses to install the new version over the old one.
keytool -genkeypair -keystore my.keystore -alias opengym -keyalg RSA -validity 10950

# align + sign (zipalign/apksigner ship with the Android SDK build-tools)
zipalign -f -p 4 app-release-unsigned.apk aligned.apk
apksigner sign --ks my.keystore --ks-key-alias opengym --out openGym.apk aligned.apk

iPhone — what's actually possible

Apple does not allow installing apps outside the App Store, so there is no .ipa download that would simply install. Your free options:

  • Self-host + PWA (recommended): open your instance in Safari → Share → Add to Home Screen. Full-screen app, no expiry, plus sync and passkeys.
  • Xcode free signing: open ios/ in Xcode with a free Apple ID as the team and run it onto your own iPhone. Apple expires the signature after 7 days; re-run from Xcode to renew.
  • AltStore: automates that 7-day re-signing over Wi-Fi via a Mac companion app.

Release notes for maintainers

  • Bump versionName/versionCode in android/app/build.gradle per release; keep them in step with frontend/package.json. versionCode must strictly increase or updates won't install over an existing APK.
  • License: openGym is AGPL-3.0, which by itself sits badly with app-store terms of service. NOTICE.md carries an app-store exception (an additional permission under AGPL §7) granted by the copyright holder — relevant only if store distribution ever happens.
  • The app requests notification permission only when the workout-day reminder is switched on, and (on Android) declares SCHEDULE_EXACT_ALARM so the reminder fires to the minute where the user allows it.