This guide walks through deploying the Interval Timer app to iPads (no Developer Mode required) using TestFlight.
- Apple Developer Program membership ($99/year)
- Xcode installed with your Apple ID signed in
- Flutter SDK installed
| Setting | Value |
|---|---|
| Bundle ID | com.petertools.intervalTimer |
| Team ID | (your Apple Developer Team ID) |
| Version | 1.0.0 |
| Build | 1 |
| Min iOS | 13.0 |
| Orientations | Landscape only |
- Go to Apple Developer — Identifiers
- Click + to register a new identifier
- Select App IDs > App
- Fill in:
- Description: Interval Timer
- Bundle ID: Select Explicit, enter
com.petertools.intervalTimer
- Under Capabilities, no special entitlements are needed (no push notifications, no HealthKit, etc.)
- Click Continue > Register
- Go to App Store Connect — My Apps
- Click + > New App
- Fill in:
- Platforms: iOS
- Name: Interval Timer
- Primary Language: English (U.S.)
- Bundle ID: Select
com.petertools.intervalTimerfrom the dropdown (registered in Step 1) - SKU:
interval-timer(any unique string, internal use only) - User Access: Full Access
- Click Create
From the project directory:
# From the project root:
# Clean and build the release IPA
flutter clean
flutter pub get
flutter build ipa --releaseThis creates an archive at:
build/ios/archive/Runner.xcarchive
And an IPA ready for upload at:
build/ios/ipa/interval_timer.ipa
Open the Xcode workspace and fix signing manually:
open ios/Runner.xcworkspaceIn Xcode:
- Select the Runner target
- Go to Signing & Capabilities
- Check Automatically manage signing
- Select your team
- Xcode will create/download the provisioning profile
- Close Xcode, run
flutter build ipa --releaseagain
Option A — using the command line:
xcrun altool --upload-app \
--type ios \
--file build/ios/ipa/interval_timer.ipa \
--apiKey YOUR_API_KEY \
--apiIssuer YOUR_ISSUER_IDTo create an API key:
- Go to App Store Connect — Users and Access — Integrations — App Store Connect API
- Click + to generate a new key
- Name:
CLI Upload, Role:Developer - Download the
.p8file and note the Key ID and Issuer ID - Place the
.p8file at~/.appstoreconnect/private_keys/AuthKey_YOURKEYID.p8
Option B — using Transporter (easier for one-off uploads):
- Install Transporter from the Mac App Store (free, by Apple)
- Open Transporter, sign in with your Apple ID
- Drag
build/ios/ipa/interval_timer.ipainto the window - Click Deliver
Option C — using Xcode directly:
- Open the archive:
open build/ios/archive/Runner.xcarchive - This opens the Xcode Organizer
- Select the archive, click Distribute App
- Choose App Store Connect > Upload
- Follow the prompts
After the upload processes (takes a few minutes):
- Go to App Store Connect — My Apps > Interval Timer
- Click the TestFlight tab
- Your build should appear under iOS Builds (status: Processing, then Ready to Test)
- If prompted for Export Compliance, select No (this app doesn't use encryption beyond standard HTTPS)
- In TestFlight, click Internal Testing in the left sidebar
- Click + next to "Internal Testing" to create a group
- Name it (e.g., "Family")
- Click + next to Testers, add people by Apple ID email
- Enable the build for this group
- Testers get an email invite immediately
- In TestFlight, click External Testing in the left sidebar
- Click + to create a group
- Add testers by email
- Submit the build for Beta App Review (usually approved within 24-48 hours)
- Once approved, testers get an email invite
On each iPad:
- Install the TestFlight app from the App Store (free)
- Open the invite email, tap View in TestFlight
- In TestFlight, tap Install next to Interval Timer
- The app appears on the home screen like any other app
No Developer Mode needed. No cable needed. Works over Wi-Fi.
When you release a new version:
-
Bump the version in
pubspec.yaml:version: 1.0.1+2 # format: name+buildNumber
The build number must always increase (App Store Connect rejects duplicate build numbers).
-
Build and upload:
flutter build ipa --release # Then upload via Transporter, xcrun, or Xcode -
In App Store Connect > TestFlight, the new build appears automatically
-
If using internal testing, it's available immediately
-
If using external testing, it goes through Beta Review again
| Problem | Fix |
|---|---|
flutter build ipa fails with "no provisioning profile" |
Open ios/Runner.xcworkspace in Xcode, enable automatic signing, select your team |
| Build number rejected ("already exists") | Increment the +N part in version: in pubspec.yaml |
| TestFlight build stuck on "Processing" | Wait up to 30 minutes; Apple processes the binary server-side |
| Testers don't receive invite | Check their email matches their Apple ID; check spam folder |
| "Export Compliance" warning | Select "No" — the app uses no custom encryption |
| App crashes on iPad but works on simulator | Check the minimum iOS version; test with flutter run --release -d <device> if you have a dev device |
- TestFlight builds expire after 90 days. Upload a new build before expiry to keep testers active.
- Internal testers must be added as App Store Connect users (with at least the "Marketing" or "Developer" role).
- External testers only need an email address — they don't need App Store Connect access.
- The app is landscape-only on iPad, which is intentional for gym use.