Skip to content

Studio: build for macOS with Swift packages only - #394

Merged
xvrh merged 1 commit into
masterfrom
claude/studio-macos-swift-packages
Sep 27, 2026
Merged

xvrh merged 1 commit into
masterfrom
claude/studio-macos-swift-packages

Conversation

@xvrh

@xvrh xvrh commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator

The studio's macOS project drops CocoaPods. Every macOS plugin it uses is a Swift package, so the Podfile was wrapping nothing but FlutterMacOS in a Pods_Runner framework. It differed from Flutter's template only by use_modular_headers!, a 2022 leftover that no pod has needed since the last plugin pod left. That is why the SDK called it non-standard and asked for a manual migration.

The change

pod deintegrate in app/macos, then delete the Podfile and its lock, the Pods-Runner xcconfig includes and the Pods project in Runner.xcworkspace. The workspace now matches the SDK's own template byte for byte. The diff is deletions only.

Nothing had to move into the Xcode project. The Podfile's platform :osx, '12.0' only ever applied to the Pods targets, and the project already sets MACOSX_DEPLOYMENT_TARGET = 12.0. The runner already has @executable_path/../Frameworks in its runpath. Nothing reads the COCOAPODS=1 define.

What it buys: a first run that needs no CocoaPods

The launcher builds the studio in a fresh working copy on a user's first run (DesktopGui.build). With the Podfile present, that build ran pod install, and on a machine without CocoaPods it stopped:

Clean flutter build macos --release before after
CocoaPods installed builds builds
No CocoaPods on PATH fails: "CocoaPods not installed or not in valid state." builds

tool/publish/install_check.dart --gui also passes locally with no CocoaPods on PATH and an empty flutter config. That is the hosted first-run path: pack, unpack, resolve, build the CLI, build the studio. CI never saw the failure because GitHub's macOS runners ship CocoaPods.

Build time: the same within noise

These were clean builds (flutter clean, Pods/ removed as in a fresh copy), alternating the two trees to cancel out load drift. Load average on the machine was 13–34.

runs (s) median
before (CocoaPods) 57.1, 56.9, 58.8 57.1
after (SwiftPM only) 55.2, 56.2, 94.2* 56.2

* The log is line for line the same as the 56 s run, so the extra time was other work on the machine. pod install itself took 0.42–0.47 s, because the only pod was FlutterMacOS. The SDK's "improve the project's build time" is about one second here.

The Swift Package Manager setting

  • Nothing needs to be set. SwiftPM is on by default on stable since Flutter 3.44.0 (Enable SPM by default on Stable flutter/flutter#184495), and the package's floor is 3.47.0. A build with enable-swift-package-manager (Not set) uses Swift packages and needs no Podfile. Tested with an empty flutter config dir.
  • An explicit opt-out still builds, the old way. With enable-swift-package-manager: false set globally, the SDK writes a template Podfile into the working copy, re-integrates Pods, runs pod install and builds, so the plugins become pod frameworks. That is where every user was before this change. They need CocoaPods, and anyone who opted out of SwiftPM has it.
  • The launcher cannot usefully pass the flag. In FlutterFeaturesConfig the environment variable ranks below the global config (pubspec ?? global ?? env ?? channel default), even though a comment in flutter_features.dart says the opposite. Measured: a global opt-out plus FLUTTER_SWIFT_PACKAGE_MANAGER=true still ran pod install. The only override is flutter: config: enable-swift-package-manager: true in app/pubspec.yaml, which does win over the opt-out (tested). It is left out: it would override a choice the user made on purpose, to spare a case that already builds.

Checked on the running studio

  • Studio (dev) launches on the migrated project with no CocoaPods warning and no plugin errors.
  • url_launcher: canLaunchUrl round trip, true.
  • package_info_plus: platform channel round trip, dev.flutterware.studio 0.6.0.
  • file_selector: Save the screenshot as PNG… presented its panel. There was no channel error, and the call stayed pending on it.
  • webview_flutter: this branch cherry-picked onto the Worlds mail-view work. A clean release build pulls webview_flutter_wkwebview in as a Swift package with no Podfile. In the running studio, Pickup order → Mia orders a flat white → Mail → Read it → Page, the live WKWebView held the rendered mail. Its text was read back from WebKit.

Every macOS plugin the studio uses is a Swift package, so CocoaPods was
wrapping nothing but FlutterMacOS in a Pods_Runner framework. The Podfile
differed from Flutter's template only by use_modular_headers!, which no
pod has needed since the last plugin pod left, so the SDK called it
non-standard and asked for a manual migration.

pod deintegrate, then the Podfile, its lock, the Pods xcconfig includes
and the Pods project in the workspace go. The deployment target (12.0)
and the runner's runpath were already set in the Xcode project itself,
so nothing had to move there.

What it buys is not build time, which is the same within noise, but a
first run that no longer needs CocoaPods: with the Podfile present,
`flutter build macos` ran pod install on every fresh working copy and
stopped at "CocoaPods not installed" on a machine without it.

Swift Package Manager is on by default on every Flutter the package
supports (stable since 3.44, floor 3.47), so nothing needs to be set. A
user who turned it off globally gets the SDK's own fallback: it writes a
template Podfile into the working copy and builds with CocoaPods, as
every user did before.
@xvrh
xvrh merged commit b108784 into master Sep 27, 2026
9 of 10 checks passed
@xvrh
xvrh deleted the claude/studio-macos-swift-packages branch September 27, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant