导出时使用额外二进制文件的 MacOS Flutter 桌面应用程序崩溃
Flutter desktop app for MacOS using extra binaries crashes when exported
我想在 App Store 之外分发 Flutter 桌面应用程序。该应用程序使用 pubspec.yaml 中的 assets
键包含一些额外的二进制文件。二进制文件最终位于应用程序内的这个目录中:
flutter_sample.app/Contents/Frameworks/App.framework/Versions/A/Resources/flutter_assets/bin
这就是我在 Process.run(...)
中使用的方法,它在本地有效。但是,如果我尝试在 Xcode 中对应用程序进行公证并将其导出,那么在尝试 运行 包含的二进制文件时应用程序将立即崩溃。我打开控制台并在 launchd.log 中找到与应用程序崩溃时间相对应的以下条目:
2022-01-07 08:28:04.875197 (gui/501/application.com.example.flutterSample.1772919.1772925) : removing job: caller = runningboardd
2022-01-07 08:28:04.875204 (gui/501 [100020]) : removing service: application.com.example.flutterSample.1772919.1772925
2022-01-07 08:28:04.875309 (gui/501/application.com.example.flutterSample.1772919.1772925) : internal event: PETRIFIED, code = 0
2022-01-07 08:28:04.875311 (gui/501/application.com.example.flutterSample.1772919.1772925) : job state = removed
我找不到有关该错误的任何其他信息。如果我使用 Process.run
将代码包含在 try-catch 块中,它不会改变任何东西,整个应用程序无论如何都会崩溃。如果我使用 handling errors page in Flutter docs.
中描述的区域或 onError 处理程序,也会发生同样的情况
额外的细节:
- 我在 *.entitlements 文件中禁用了 com.apple.security.app-sandbox,使用它 运行即使在本地进程也无法运行
- 我在 Xcode 中启用了强化 运行time,它需要对应用程序进行公证。
- 应用程序也会崩溃,如果相反或从 Xcode 导出我简单地存档构建目录(使用
tar
)并通过互联网发送(或设置 com.apple.quarantine
使用 xattr
).如果我只是打包和解包而不将其标记为隔离,它就不会崩溃。这是有道理的,但我预计对应用程序进行公证会解决它。
那么,我可以做些什么来防止这些崩溃,或者至少在它们发生时获得更多详细信息以便我可以进一步调查?
首先尝试将您的二进制文件从资产文件夹复制到其他地方。假设复制到 /tmp/myfile
。然后确保您对它具有可执行权限(chmod +x /tmp/myfile
使用 shell;应该有类似的使用代码)。然后执行那个二进制文件。
这是一种常见的做法,至少对于像 Android 这样的平台来说是这样。因为在 android 中,资产没有“正常”路径,因此您必须将其复制出来,IIRC。
如果这个方法行得通,那就太好了;即使没有,现在您也可以在 shell 中手动调用 /tmp/myfile
以查看发生了什么。
事实证明,这是路径问题。如果我转到我的项目目录,然后进入调试构建目录:
$ cd build/macos/Build/Products/Debug
然后从这一点我可以访问两个相同的资产目录:
$ ls -lh App.framework/Versions/A/Resources/flutter_assets
(output omitted)
$ ls -lh flutter_sample.app/Contents/Frameworks/App.framework/Versions/A/Resources/flutter_assets
(the same output, omitted)
事实证明,我实际上是在尝试调用第一个资产目录中的二进制文件(即使我在问题中发布了第二个)。显然,当应用程序打包分发时,另一个是正确的。更改后,二进制文件在导出的、经过公证的应用程序中工作。
我想在 App Store 之外分发 Flutter 桌面应用程序。该应用程序使用 pubspec.yaml 中的 assets
键包含一些额外的二进制文件。二进制文件最终位于应用程序内的这个目录中:
flutter_sample.app/Contents/Frameworks/App.framework/Versions/A/Resources/flutter_assets/bin
这就是我在 Process.run(...)
中使用的方法,它在本地有效。但是,如果我尝试在 Xcode 中对应用程序进行公证并将其导出,那么在尝试 运行 包含的二进制文件时应用程序将立即崩溃。我打开控制台并在 launchd.log 中找到与应用程序崩溃时间相对应的以下条目:
2022-01-07 08:28:04.875197 (gui/501/application.com.example.flutterSample.1772919.1772925) : removing job: caller = runningboardd
2022-01-07 08:28:04.875204 (gui/501 [100020]) : removing service: application.com.example.flutterSample.1772919.1772925
2022-01-07 08:28:04.875309 (gui/501/application.com.example.flutterSample.1772919.1772925) : internal event: PETRIFIED, code = 0 2022-01-07 08:28:04.875311 (gui/501/application.com.example.flutterSample.1772919.1772925) : job state = removed
我找不到有关该错误的任何其他信息。如果我使用 Process.run
将代码包含在 try-catch 块中,它不会改变任何东西,整个应用程序无论如何都会崩溃。如果我使用 handling errors page in Flutter docs.
额外的细节:
- 我在 *.entitlements 文件中禁用了 com.apple.security.app-sandbox,使用它 运行即使在本地进程也无法运行
- 我在 Xcode 中启用了强化 运行time,它需要对应用程序进行公证。
- 应用程序也会崩溃,如果相反或从 Xcode 导出我简单地存档构建目录(使用
tar
)并通过互联网发送(或设置com.apple.quarantine
使用xattr
).如果我只是打包和解包而不将其标记为隔离,它就不会崩溃。这是有道理的,但我预计对应用程序进行公证会解决它。
那么,我可以做些什么来防止这些崩溃,或者至少在它们发生时获得更多详细信息以便我可以进一步调查?
首先尝试将您的二进制文件从资产文件夹复制到其他地方。假设复制到 /tmp/myfile
。然后确保您对它具有可执行权限(chmod +x /tmp/myfile
使用 shell;应该有类似的使用代码)。然后执行那个二进制文件。
这是一种常见的做法,至少对于像 Android 这样的平台来说是这样。因为在 android 中,资产没有“正常”路径,因此您必须将其复制出来,IIRC。
如果这个方法行得通,那就太好了;即使没有,现在您也可以在 shell 中手动调用 /tmp/myfile
以查看发生了什么。
事实证明,这是路径问题。如果我转到我的项目目录,然后进入调试构建目录:
$ cd build/macos/Build/Products/Debug
然后从这一点我可以访问两个相同的资产目录:
$ ls -lh App.framework/Versions/A/Resources/flutter_assets
(output omitted)
$ ls -lh flutter_sample.app/Contents/Frameworks/App.framework/Versions/A/Resources/flutter_assets
(the same output, omitted)
事实证明,我实际上是在尝试调用第一个资产目录中的二进制文件(即使我在问题中发布了第二个)。显然,当应用程序打包分发时,另一个是正确的。更改后,二进制文件在导出的、经过公证的应用程序中工作。