Flutter运行iOS26真机的两个问题
2025年12月17日 18:14
一、Debug编译崩溃
../../../flutter/third_party/dart/runtime/vm/virtual_memory_posix.cc: 428: error: mprotect failed: 13 (Permission denied)
在iOS上Dart不管是JIT运行还是进行hotload的时候,都需要涉及代码在内存从RW变成RX的调整,而这在Flutter低版本是通过
mprotect完成,而这在iOS 26被禁止了
所以Flutter在Debug模式下真机运行iOS 26设备就崩溃了。如果确实需要在iOS 26上真机调试,方案如下:
- 目前测试最新的3.38.5版本可以正常在Debug模式运行iOS 26设备。
- 如果不能升级Flutter版本,只能暂时使用Release或Profile模式运行(修改iOS项目Scheme,设置run->Build Configuration)
二、Flutter适配UIScene
当我的iOS 26的设备正常运行后,发现Xcode控制台有一行打印:
UIScenelifecycle will soon be required. Failure to adopt will result in an assert in the future.
强制使用UIScene不然未来就可能触发断言,太可怕了😱那就顺便做了吧。
Flutter最低版本:
environment:
sdk: ^3.10.0
flutter: ">=3.38.0"
方案一: 自动化迁移,适合iOS AppDelegate文件没有大量定制化修改,在项目终端运行命令:
flutter config --enable-uiscene-migration
迁移成功后,会在构建日志中看到 "Finished migration to UIScene lifecycle" 的提示,否则工具会给出警告,并提示你手动迁移。
方案二: 手动迁移
-
AppDelegate移除window生命周期相关的方法,使用UIScene lifecycle的对应方法,保留application(_:didFinishLaunchingWithOptions:)方法,移除所有创建和设置window的代码 -
AppDelegate类遵循协议:FlutterImplicitEngineDelegate,并在didInitializeImplicitFlutterEngine方法中注册插件,并将创建Method Channels或Platform Views的逻辑都迁移到此处,因为在didFinishLaunchingWithOptions执行时,FlutterViewController可能还不存在
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func didInitializeImplicitFlutterEngine(_ engineBridge: any FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
// Channel、Platform Views
}
}
- 创建
SceneDelegate.swift文件,基础定义如下:
import UIKit
import Flutter
class SceneDelegate: FlutterSceneDelegate {
}
-
info.plist添加Application Scene Manifest相关key:
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
key缺失可能会导致启动黑屏或控制台打印xxxkey缺失,其中key:
- UISceneConfigurationName:
Default Configuration或flutter均可 - UISceneDelegateClassName:
FlutterSceneDelegate或$(PRODUCT_MODULE_NAME).SceneDelegate均可
到此基础配置就完成了,恭喜你demo项目可以正常运行了,如果你的项目其他定制化修改还需要迁移,详细可以参考下面的Flutter Docs。