For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /developers/apple/architecture.md.

架构

Home Assistant iOS 是一个多目标 Apple 平台项目。它最初是一个围绕 web 体验的 companion app,现已发展为一个混合代码库,具备原生 onboarding、传感器、widgets、Apple Watch 支持、CarPlay、App Intents 以及由通知驱动的功能。

该仓库将特定应用的代码、共享平台代码、extension 和一个小的 Swift server 组件组合在单个 workspace 中。

核心原则

多目标设计

该仓库的组织方式尽可能在各目标间共享逻辑,同时允许在需要时使用平台特定实现。数据库访问、网络、设计系统组件、通知、widgets 和共享模型等跨领域关注点都放在 common 模块中,以便多个目标可以复用它们。请参阅目标指南,了解每个 surface 的概述。

混合 UI 栈

该项目同时使用 SwiftUIUIKit。更新的工作流和组件越来越多地使用 SwiftUI,而遗留和平台特定的集成仍直接依赖 UIKit 和其他 Apple 框架。

仓库结构

Sources/App

这里包含 iOS 应用特定的功能,例如 onboarding、设置、场景、摄像头、通知、web/frontend 集成、kiosk 功能和工具。

Sources/Shared

这是共享代码库的核心。它包括:

  • API 和网络支持
  • 围绕 GRDB 构建的数据库代码
  • 共享模型和 domain 逻辑
  • 设计系统工具
  • Widget 和通知支持
  • 位置、Assist 和服务集成

Sources/Extensions

该区域包含 extension 和系统集成的代码,包括:

  • Widgets
  • App Intents
  • Share extension
  • 通知服务和内容 extension
  • Matter 支持
  • Push provider 支持

其他重要目录

  • Sources/CarPlay: CarPlay 模板和功能逻辑
  • Sources/WatchSources/WatchApp: Apple Watch 通信和 watch app 代码
  • Sources/Thread: Thread 凭据管理和共享流程
  • Sources/MacBridge: Mac 构建使用的 macOS 特定 bridge 代码
  • Sources/PushServerSources/SharedPush: 基于 Swift 包的 server 和共享 push 逻辑
  • Tests: 应用、共享、UI 和 widget 测试
  • fastlane: Linting、测试、版本控制和构建自动化

关键技术

当前代码库大量使用:

值得注意的第三方依赖

除了 Apple 框架之外,应用还依赖几个开源库。完整列表位于 Podfile 中,但以下是被频繁触碰的:

实践中应用的架构模式

共享环境访问

项目在许多地方使用共享的 Current 环境模式(参见 How to control the world)来访问依赖和服务。实际上,这意味着单个 Current 值将应用所需的依赖分组在一起,这使得它们很容易从任何地方读取,也很容易在测试中替换。代码库对此处理得很谨慎,以至于 SwiftLint 有一条自定义规则来防止随意的重新赋值。

Extension 是一等公民

我们鼓励你从一开始就把 widgets、通知、CarPlay、watchOS 支持和 App Intents 考虑在内。应用需要良好地在所有这些 surface 上工作,同时保持代码质量,因此变更往往需要考虑 extension-safe 代码、共享存储和跨目标复用。

App 加平台 surface

一个功能可能会触及主应用之外的部分。例如,一个实体操作可能会出现在应用 UI、widgets、Apple Watch、App Intents 或 CarPlay 中。在开始编码之前,值得检查一下变更是否应该放在 Sources/AppSources/Shared 或某个 extension 目标中。

如何浏览代码库

下图显示了顶部的实际 Xcode 发布产品,以及为每个产品提供输入的 Sources/* 目录。可以双向阅读:

  • 从产品开始(例如,Apple Watch 应用):沿着箭头向外看,可以看到包含在其中的每个 source 目录。
  • 从 source 目录开始(例如,Shared):沿着入箭头看,可以看到消费它的每个产品。

有一些组件位于主 workspace 之外:

如果你是仓库的新手,一个很好的定位方法是:

  1. Sources/App 开始,了解主 iPhone 和 iPad 应用的组织方式。大多数功能都源自这里。
  2. 将多个目标需要的逻辑放在 Sources/Shared 中,以便 extension、watch 和 CarPlay 可以复用。
  3. 对于特定目标的功能(例如仅 watch 或仅 widget 的变更),在 Sources/ExtensionsSources/CarPlaySources/Watch 中查找匹配的 surface。
  4. 在添加新代码之前,在 Tests/AppTests/Shared 中查看示例。