Flutter 运行 iOS 真机技巧

309 阅读2分钟

在 iOS 17 之后,Flutter 无法直接通过 flutter run 在 iOS 真机设备上运行,会报出现类似 OS Error: Can't assign requested address, errno = 49 的错误。

出错原因可能是:Flutter 在真机调试模式下用于热重载 / DevTools 连接的 mDNS 服务发现(使用 multicast_dns 包)。 但在 iOS 真机上,部分网络环境(例如手机热点网络)会禁止多播,或者系统安全策略不允许多播绑定(iOS 17 后更严格)。

解决方法如下:Attach

方法一:

  1. 在终端中执行如下命令,选择 iOS 真机设备运行(启动 Xcode 在 真机上运行)

    flutter run --no-resident		# --no-resident 选项告诉 Flutter:运行完 app 后,不要保持命令行(flutter tools)常驻
    
  2. 然后再通过如下命令进行 attach

    flutter attach --debug-uri=http://127.0.0.1:50088/afyBA2t9LHI=/
    

    注意:这里的 URI 是应用初始运行起来 XCode 的终端默认输出flutter: The Dart VM service is listening on http://127.0.0.1:50088/afyBA2t9LHI=/

    也可以在 AppDelegate.swift 中在 return super.application 之前,通过如下代码获取:

    // 这个地址是动态分配的,每次运行都不一样
    print("Dart VM Service URI: \(Bundle.main.object(forInfoDictionaryKey: "DartServiceUri") ?? "unknown")")
    
  3. 最后在编辑器中进行代码编辑,然后再终端执行 hot reloadhot restart

    r  # hot reload
    R  # hot restart
    

方法二:

方法一 需要频繁的在 终端编辑器 直接来回切换;

下面的方法,基于 VSCode 中操作,避免手动开终端 attach/热重载(直接 F5 运行即可)

  1. VSCode 的终端中执行如下命令,选择 iOS 真机设备运行(启动 Xcode 在 真机上运行)

    flutter run --no-resident		# --no-resident 选项告诉 Flutter:运行完 app 后,不要保持命令行(flutter tools)常驻
    
  2. 创建 / 修改 launch.json 文件,修改内容如下

    在项目根目录下(和 pubspec.yaml 同级)新建 / 编辑 .vscode/launch.json 文件。(如果没有,先点击 VSCode 左侧的 “Run and Debug” → “create a launch.json file”。)

    // launch.json
    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "flutter_demo",
                "request": "launch",
                "type": "dart",
            },
            {
                "name": "flutter_demo (profile mode)",
                "request": "launch",
                "type": "dart",
                "flutterMode": "profile"
            },
            {
                "name": "flutter_demo (release mode)",
                "request": "launch",
                "type": "dart",
                "flutterMode": "release"
            }, 
          	// 添加一个 Attach 的模式
            {
                "name": "flutter_demo (attach mode)",
                "request": "attach",			// 将运行方式修改为 attach 
                "type": "dart",
                "vmServiceUri": "http://127.0.0.1:50088/afyBA2t9LHI=/",		// 添加 VM 地址
            },
        ]
    }
    

注意:这里的 URI 是应用初始运行起来 XCode 的终端默认输出flutter: The Dart VM service is listening on http://127.0.0.1:50088/afyBA2t9LHI=/

也可以在 AppDelegate.swift 中在 return super.application 之前,通过如下代码获取:

// 这个地址是动态分配的,每次运行都不一样
print("Dart VM Service URI: \(Bundle.main.object(forInfoDictionaryKey: "DartServiceUri") ?? "unknown")")
  1. VSCode 左侧的(运行和调试) “Run and Debug” → 中选择刚才添加 attach mode 模式,F5 运行(记得 device 选择 iOS 真机设备),attach 成功后,后续就可以正常编码,进行 热重载热重启 了(包括断点等)

说明

每次重新运行后 VM Service URI 都是会变化的,注意及时更新!