跪拜 Guibai
← All articles
Flutter · Dart · iOS

Flutter 3.47 Decouples Material Design; iOS 27 Will Crash Unmigrated Apps

By GitLqr ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

iOS 27 turns the UIScene requirement into a hard crash, not a warning — CI pipelines running Xcode 26 today will silently pass, then break overnight when Xcode 27 lands. Separately, the Material/Cupertino split means package maintainers need to ship a major release, and every app team must run the automated migration or risk dependency conflicts.

Summary

Flutter 3.47 and Dart 3.13 are foundation-level releases. The design systems `material_ui` and `cupertino_ui` are now standalone packages on pub.dev, decoupled from the quarterly SDK cadence and free to iterate weekly. A compatibility bridge lets apps adopt the new imports immediately even when third-party plugins still reference the old SDK paths. Dart 3.13 stabilizes primary constructors, auto-groups imports during formatting, and introduces FFI tree-shaking so compiled binaries drop unused native symbols. Impeller also becomes the default desktop renderer, eliminating first-frame shader compilation jank by pre-compiling a fixed shader set at build time.

Takeaways
Run `dart fix --apply --code=migrate_design_widgets` to switch imports from `package:flutter/material.dart` to `package:material_ui/material_ui.dart`.
Add `material_ui` and `cupertino_ui` to `pubspec.yaml` manually if the automated fix misses them.
Wrap your `MaterialApp` builder with `MaterialUiCompatibilityBridge` so unmigrated third-party plugins keep working.
Test your app on the iOS 27 beta immediately — apps using the old UIKit lifecycle will crash at launch under Xcode 27.
Custom `AppDelegate` code and plugins on the old lifecycle model require manual migration; the Flutter CLI won't fix them.
Impeller is now the default desktop renderer, pre-compiling shaders at build time to eliminate first-frame jank.
Dart 3.13 stabilizes primary constructors, auto-groups imports via `dart format`, and supports FFI tree-shaking with the `@RecordUse()` annotation.
Wasm builds gain deferred loading (`--enable-wasm-deferred-loading`) to reduce initial page load time for large web apps.
Conclusions

Moving Material and Cupertino to pub.dev turns the design system from a framework component into a framework consumer — a structural shift that lowers the barrier for custom design systems and lets UI iterate independently of rendering engine changes.

The compatibility bridge is a pragmatic escape hatch: it acknowledges that the plugin ecosystem won't migrate in lockstep and prevents the decoupling from becoming a blocking upgrade.

iOS 27's hard crash on missing UIScene is a time-bomb for CI. The danger isn't the migration work itself but the silent pass on current Xcode versions that will flip to failures the moment build infrastructure updates.

FFI tree-shaking via `@RecordUse()` changes the calculus for package authors who bundle native code — unused symbols now get stripped automatically, shrinking binary size without manual pruning.

Concepts & terms
UIScene lifecycle
Apple's modern UIKit app architecture that supports multiple windows and scenes. iOS 27 requires it; apps still using the older AppDelegate-only lifecycle will crash on launch.
Impeller
Flutter's newer rendering engine that pre-compiles a fixed set of shaders at build time instead of compiling them on-demand at runtime, avoiding first-frame jank that Skia suffers from.
FFI tree-shaking
A Dart compiler optimization that removes unused native (C/C++) function symbols from the final binary. Package authors opt in with the `@RecordUse()` annotation to tell the compiler which symbols are actually called.
MaterialUiCompatibilityBridge
A widget introduced in Flutter 3.47 that wraps the widget tree so third-party plugins still referencing the old `package:flutter/material.dart` imports continue to function after an app migrates to the standalone `material_ui` package.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗