Lyft创建iOS应用扩展的挑战

Lyft iOS 应用扩展的复杂性处理

Lyft 的工程师 Artur Stepaniuk 和 Max Husar 最近发表了一篇文章,详细介绍了如何在 iOS 应用中创建扩展,同时不违反 Apple 对 RAM 和二进制大小的严格限制,也不影响用户体验。

背景与挑战

Lyft 的 iOS 应用包含一个与 Apple 地图集成的扩展,允许用户在地图应用中直接查看 Lyft 的出行信息。创建 iOS 应用扩展的主要挑战在于管理依赖关系,以最大限度地重用应用和扩展之间的代码,同时优化二进制大小和内存使用。

由于无法使用动态链接(避免启动时加载到内存中导致应用启动过慢),静态链接成为唯一可行的选择。然而,这导致应用的二进制大小和内存占用增加。二进制大小的增加可能导致下载和安装时间延长,甚至可能触发 Apple 的 200MB 下载限制,从而在蜂窝数据下载时显示额外的确认对话框。

内存与二进制大小优化

Lyft 的工程师发现,扩展的内存使用限制在 20MB 到 50MB 之间,具体取决于 iOS 版本、设备型号等因素。为了减少二进制大小和内存占用,Lyft 工程师分析了应用的依赖图,识别出对二进制大小和内存占用贡献最大的模块。

工具与分析方法

Lyft 使用 Bazel 构建系统,并借助 Graphviz 工具将 Bazel 生成的依赖图可视化。为了详细测量二进制大小的影响,工程师使用 binary-size-diff 工具,该工具可以比较基础分支和特定拉取请求之间的二进制大小差异,从而评估移除或包含某个依赖的实际效果。

依赖关系的优化

通过 Bazel 的查询功能,工程师可以展示两个模块之间的传递依赖关系。例如,以下命令可以显示模块之间的依赖路径:

bazel query 'allpaths(INITIAL_MODULE_PATH:INITIAL_MODULE_NAME, TARGET_MODULE_PATH:TARGET_MODULE_NAME)' --output=graph | grep -v '  node \[shape=box\];' > relations.dot

通过这种方式,工程师可以识别并移除不必要的依赖,或者使目标模块不再依赖较大的模块。在特定情况下,Lyft 团队决定复制一个服务,以创建一个最小化的依赖关系,从而打破与较大模块的依赖。

优化成果

通过上述方法,Lyft 工程师成功将扩展的二进制大小从 45MB 减少到 15MB。虽然对于服务器端或桌面应用来说,30MB 的减少并不显著,但这相当于 Apple 200MB 安全限制的 15%,对于移动应用来说具有重要意义。

其他细节

文章还涉及了发布应用扩展的其他细节,如如何确保扩展在所有支持的区域可用、使用 APPLICATION_EXTENSION_API_ONLY 构建设置的影响,以及 SiriKit 的特殊性。对于对这些话题感兴趣的读者,建议阅读原文以获取更多信息。

总结

Lyft 的工程师通过精细的依赖管理和工具使用,成功优化了 iOS 应用扩展的二进制大小和内存占用,确保在不违反 Apple 限制的前提下提供良好的用户体验。

阅读 12
0 条评论