前言

我们在写 flutter 项目时每次执行 pub clean 后, .ios 项目会重新创建,项目的 bitcode 会重置为 true,项目就是编译失败,相信大家都遇到过,每次都需要手动设置 bitcode = false,考虑这种手动操作繁琐让我团队成员不胜其扰。同时我近期有学习 Python ,就拿这练练手,通过 py 脚本一键处理这个问题,大家也就能愉快开发了~😆
image.png

bitcode 问题

image.png

思考

之前有想过用 shellruby 等去实现这个,搜索下发现有人提高了思路 传送门,我尝试过用 stackoverflow上 25 个赞的建议后,尝试发现能执行,但编译失败就放弃。后来采用 pbxproj 刚好是 Python 写的,是个契机,学以致用。
image.png

  1. #pod install
  2. xcodebuild -target house591 -configuration Debug ENABLE_BITCODE=YES
  3. xcodebuild -target house591 -configuration Test ENABLE_BITCODE=YES
  4. xcodebuild -target house591 -configuration Release ENABLE_BITCODE=YES

环境

首先需要的是安装 Python3 环境,这块我就不细说了。如果想用 py 虚拟环境,可以使用 pyenv 参考这篇 传送门 (by 洵锋同学写的),我用的是 Python 3.8.10

插件

设置 Xcode build Setting 使用的是第三方插件 传送门

  1. # 安装如下
  2. pip3 install pbxproj

使用设置 Flutter 项目 Bitcode 核心代码

  1. # 设置 bitcode
  2. def set_bit_code_path(path, is_close_bitcode=True):
  3. project = XcodeProject.load(path)
  4. bitcode_str = "NO"
  5. if not is_close_bitcode:
  6. bitcode_str = "YES"
  7. print(f"set_bit_code_path 当前项目路径:{path} bitcode_str: {bitcode_str}")
  8. set_bit_code_flag(project, bitcode_str, configuration_name="Debug")
  9. set_bit_code_flag(project, bitcode_str, configuration_name="Profile")
  10. set_bit_code_flag(project, bitcode_str, configuration_name="Release")
  11. project.save()
  12. # 设置 bitcode 参数
  13. def set_bit_code_flag(project, bitcode_str, target_name="Runner", configuration_name='Debug'):
  14. project.set_flags('ENABLE_BITCODE', bitcode_str, target_name=target_name, configuration_name=configuration_name)

使用

方式一

  • 直接终端执行,我们自己是使用 ssh 工具 shuttle 一键执行-目前我们的项目往 Flutter 技术栈的方向转,所以建了三个 Flutter module 业务组件,因此我这边只建三个 Flutter 项目的脚本路径,后续视情况补充脚本命令。image.png
  • 当然我们也可以直接终端执行,如下

    1. cd /Users/zhengzeqin/Desktop/GitLab/TWHouseScript; python disable_bitcode.py -p '/Users/zhengzeqin/Desktop/GitLab/tw591_salehouse' -s close
  • 其实 shuttle 的命令是用 json 来设置,可以结合 [jsonnet](https://github.com/google/jsonnet) 去动态生成,这样就可以复用给别人

    方式二

    如果不想像上述那样,多个项目配合 shuttle 命令。路径我们也可以写在脚本里,每个 Flutter 项目配置自己的 Python 脚本命令,记得定义好自己的项目路径就好,具体如下

  1. # 定义项目 module 文件名
  2. _module_names = ['tw591_salehouse']
  3. # 项目的父目录
  4. _file_path = "/Users/zhengzeqin/Desktop/GitLab/"
  5. # flutter project.pbxpro
  6. _flutter_pro = '/.ios/Runner.xcodeproj/project.pbxproj'
  7. # 设置 bitcode
  8. def set_bit_code(file_path, module_name):
  9. path = file_path + module_name + _flutter_pro
  10. # print("当前项目路径:", path)
  11. set_bit_code_path(path)
  12. # 本地文件配置路径处理 bitcode
  13. def handle_projects_bit_code():
  14. for module_name in _module_names:
  15. set_bit_code(_file_path, module_name)
  16. if __name__ == "__main__":
  17. # 本地文件配置路径处理 bitcode
  18. handle_projects_bit_code()
  19. # 如果是 flutter 同级下配置可以这样读取 project.pbxproj 路径
  20. current_path = os.path.abspath(os.curdir) + _flutter_pro
  21. print(current_path)

完整脚本代码

  1. # -*- coding: utf-8 -*-
  2. # -*- author: zhengzeqin -*-
  3. # -*- date: 2022-03-01 -*-
  4. # 需要安装依赖库
  5. # pip3 install pbxproj
  6. import os
  7. import getopt
  8. from pbxproj import XcodeProject
  9. import sys
  10. # 定义 flutter 项目 module 文件名
  11. _module_names = ['tw591_salehouse']
  12. # 项目的父目录
  13. _file_path = "/Users/zhengzeqin/Desktop/GitLab/"
  14. # flutter project.pbxpro
  15. _flutter_pro = '/.ios/Runner.xcodeproj/project.pbxproj'
  16. # 本地文件配置路径处理 bitcode
  17. def handle_projects_bit_code():
  18. for module_name in _module_names:
  19. set_bit_code(_file_path, module_name)
  20. # 设置 bitcode
  21. def set_bit_code(file_path, module_name):
  22. path = file_path + module_name + _flutter_pro
  23. # print("当前项目路径:", path)
  24. set_bit_code_path(path)
  25. # 设置 bitcode
  26. def set_bit_code_path(path, is_close_bitcode=True):
  27. project = XcodeProject.load(path)
  28. bitcode_str = "NO"
  29. if not is_close_bitcode:
  30. bitcode_str = "YES"
  31. print(f"set_bit_code_path 当前项目路径:{path} bitcode_str: {bitcode_str}")
  32. set_bit_code_flag(project, bitcode_str, configuration_name="Debug")
  33. set_bit_code_flag(project, bitcode_str, configuration_name="Profile")
  34. set_bit_code_flag(project, bitcode_str, configuration_name="Release")
  35. project.save()
  36. # 设置 bitcode 参数
  37. def set_bit_code_flag(project, bitcode_str, target_name="Runner", configuration_name='Debug'):
  38. project.set_flags('ENABLE_BITCODE', bitcode_str, target_name=target_name, configuration_name=configuration_name)
  39. if __name__ == "__main__":
  40. # 本地文件配置路径处理 bitcode
  41. # handle_projects_bit_code()
  42. # 如果是 flutter 同级下配置可以这样读取 project.pbxproj 路径
  43. # current_path = os.path.abspath(os.curdir) + _flutter_pro
  44. # print(current_path)
  45. argv = sys.argv[1:]
  46. # 项目路径
  47. project_path = ""
  48. # 默认关闭
  49. is_close_bitcode = True
  50. try:
  51. opts, args = getopt.getopt(argv, "p:s:", ["path=", "switch="])
  52. except getopt.GetoptError:
  53. print('disable_bitcode.py -p "项目路径"')
  54. sys.exit(2)
  55. print("opts ===>", opts)
  56. for opt, arg in opts:
  57. if opt in ["-p", "--path"]:
  58. project_path = arg
  59. if len(project_path) == 0:
  60. print('请输入项目的地址')
  61. sys.exit('请输入项目的地址')
  62. if opt in ["-s", "--switch"]:
  63. if arg == "open":
  64. is_close_bitcode = False
  65. if arg == "close":
  66. is_close_bitcode = True
  67. # 获取需要修复项目的路径
  68. path = project_path + _flutter_pro
  69. # 设置 bitcode = false
  70. set_bit_code_path(path, is_close_bitcode)

后序思考 🤔

上述解决的是 iOS `` bitcode = true编译失败问题,其实 Android 也有个默认版本低引起编译失败问题,是不是我们也可以通过脚本去解决呢?