Build a Flutter iOS app on Windows or Linux
Develop Flutter on Windows or Linux, prepare a reproducible iOS project, build it remotely with Xcode, and send the signed app to TestFlight.
· 10 min read
You can develop a Flutter app on Windows or Linux and publish its iOS version without owning a Mac. Dart, widgets, tests, Android, web, and desktop targets run locally. The iOS Runner, native plugins, Xcode archive, code signing, and TestFlight release still need macOS.
Keep the complete Flutter application in a reproducible repository, send it to a cloud Mac, and let the remote environment reconstruct the iOS configuration before building.
Push the Flutter application root containing both pubspec.yaml and ios/. Pushing only the iOS directory omits the Dart packages and Flutter tooling inputs required to create the native build.
What works outside macOS?
| Task | Windows / Linux | Remote Mac |
|---|---|---|
| Write Dart and Flutter widgets | Yes | Can build again |
| Run analysis and Flutter tests | Yes | Optional repeat |
| Run Android, web, or supported desktop target | Yes | Not required |
| Compile the iOS Runner and native plugins | No Xcode | Required |
| Run iOS Simulator | No | Requires interactive Mac |
| Sign and upload to TestFlight | Can request | Required |
Flutter's official iOS setup guide installs Xcode before running on an iOS device or Simulator. Flutter shares a large part of the application, but its iOS output is still a native Apple target.
Prepare a complete Flutter repository
MyApp/
├── pubspec.yaml
├── pubspec.lock
├── .fvmrc # recommended exact Flutter version
├── lib/
├── test/
├── assets/
└── ios/
├── Runner.xcodeproj/
├── Runner.xcworkspace/
├── Runner/
└── Podfile # when the project still uses CocoaPods- ·Commit
pubspec.lockfor an application. - ·Pin an exact Flutter SDK version in
.fvmrcwhen reproducibility matters. - ·Declare every asset in
pubspec.yamland preserve filename case. - ·Commit the complete
ios/Runner project and its bundle settings. - ·Keep generated build directories and local signing data out of Git.
- ·Review plugin versions and their minimum iOS deployment targets.
NoMac can select a tested Flutter version when there is no exact pin, but an exact project pin gives the clearest repeatability. The declared Dart and Flutter constraints must agree with the lockfile.
Check the iOS Runner before the first build
Set a unique bundle identifier matching the App Store Connect record. Confirm the product name, deployment target, version, build number, app icon, launch screen, supported orientations, capabilities, and permission descriptions.
Flutter plugins can bring native Swift, Objective-C, CocoaPods, or Swift Package Manager dependencies into the build. A package that works on Android can still require a newer iOS target or an Apple capability.
Run the fast checks locally
flutter pub get flutter analyze flutter test
Also run the app on an Android device, web browser, or supported desktop target when useful. These checks validate Dart and much of the shared interface. They do not prove that the iOS Runner, native plugins, Pods, entitlements, or signing are correct.
Connect Flutter to the cloud build
From the directory containing pubspec.yaml, authenticate:
npx @nomac/cli login
Register npx @nomac/cli mcp with your agent, then push from the same root. NoMac detects the Flutter project, restores its dependencies, prepares the iOS build configuration, and selects the workspace.
Run flutter analyze and flutter test. Confirm pubspec.lock is committed and the Flutter version is exact. Push the complete root containing pubspec.yaml and ios/, then run a NoMac smoke build. On failure, distinguish Dart package, Flutter toolchain, plugin, CocoaPods, Xcode, and signing errors.
The Flutter-to-TestFlight loop
1. Smoke-build the iOS target
Call push_project and run workflow=smoke. Poll status until the build finishes. Use get_failure to retrieve the first actionable diagnosis.
2. Fix the owning layer
- ·Dart solver failures belong to constraints and
pubspec.lock. - ·Missing generated configuration means the Flutter preparation step did not complete.
- ·Plugin deployment-target conflicts need compatible plugin or iOS target choices.
- ·CocoaPods or Swift package failures belong to native dependency configuration.
- ·Bundle ID, capability, and profile mismatches belong to signing setup.
3. Build the signed release
After the smoke build passes, run workflow=release. NoMac creates the signed archive and uploads it to App Store Connect. Wait for processing, then install through TestFlight.
4. Test the iOS-specific behavior
Verify startup, text input, safe areas, scrolling, back gestures, dark mode, Dynamic Type, permission dialogs, notifications, deep links, backgrounding, restoration, and every native plugin. Compare the behavior with Android only where the product should genuinely match.
Important limitation: Flutter add-to-app
NoMac's automatic Flutter path is for a complete Flutter application with its iOS Runner. Flutter add-to-app modules embedded inside a separate native host need a project-specific integration and are not supported by this automatic path. Use an interactive Mac or a custom CI workflow for that architecture.
Flutter's current iOS add-to-app documentation also shows that this is a separate integration flow, now moving toward Swift Package Manager for current Flutter releases.
Common mistakes
- ·Pushing
ios/without the Flutter application root. - ·Omitting
pubspec.lockor using a floating Flutter channel. - ·Depending on generated local files that a clean build cannot reconstruct.
- ·Assuming an Android pass proves iOS plugin compatibility.
- ·Changing the iOS deployment target to silence one package without checking user impact.
- ·Testing only Flutter's debug behavior and never the signed release build.
Publish the Flutter app
Run review_lint, inspect privacy manifests and data collection for every plugin, prepare screenshots from the processed TestFlight build, and verify the App Store metadata. Provide review credentials if the app has login. Stage the exact build and require human confirmation before submission.
Follow the complete 2026 publishing guide for the store steps. Windows or Linux remains the Flutter development machine; the cloud Mac performs the Apple-specific part.