Files
xianyan/iOS_macOS_Developer_Guide.md
Developer d4d8746252 docs: 更新 iOS/macOS 开发者指南 v4
- 新增 bitsdojo_window → window_manager 替换说明
- 新增 flutter_vibrate iOS TARGET_OS_SIMULATOR 兼容性修复说明
- 更新文档版本号至 v4
2026-06-01 09:43:44 +08:00

682 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iOS / macOS 开发者指南
> 本项目同时支持 iOS、macOS、Android、鸿蒙(HarmonyOS) 四端。
> 鸿蒙端使用定制 Flutter SDK`flutter-ohos`),在 `TargetPlatform` 枚举中新增了 `TargetPlatform.ohos`
> 并对大量三方库做了本地化适配。iOS/macOS 开发者需了解以下关键事项,避免踩坑。
---
## 一、环境准备与项目拉取
### 1.1 Flutter SDK 选择
| 平台 | 推荐SDK | 说明 |
|---|---|---|
| iOS / macOS | **官方 Flutter SDK** | 标准 stable/beta 渠道即可 |
| 鸿蒙 | flutter-ohos 定制SDK | 包含 `TargetPlatform.ohos` 等扩展,仅在鸿蒙开发机上使用 |
| Android | 官方 Flutter SDK | 同 iOS |
> ⚠️ **iOS/macOS 开发使用官方 Flutter SDK 即可**无需安装鸿蒙定制SDK。
> 不要用鸿蒙SDK编译iOS/macOS反之亦然SDK不兼容会导致编译错误。
### 1.2 克隆仓库
```bash
# 克隆项目仓库
git clone <仓库URL> xianyan
cd xianyan
# 查看当前分支
git branch -a
# 切换到开发分支(如需)
git checkout feature/xxx
# 或直接在 main 分支开发
git checkout main
```
### 1.3 修改 pubspec.yaml 并安装依赖
MacBook Pro 端需要将 `pubspec.yaml` 中的本地包引用替换为远程版本号(详见 §2.2)。
```bash
# 1. 确认使用官方 Flutter SDK
flutter --version # 应显示官方版本,非 flutter-ohos
# 2. 修改 pubspec.yaml参见 §2.2 替换清单)
# 3. 获取依赖
flutter pub get
# 4. iOS 编译验证
flutter build ios --no-codesign
# 5. macOS 编译验证
flutter build macos
# 5. 防止误提交 pubspec.yaml
git stash push -m "macOS-local-pubspec" pubspec.yaml
```
---
## 二、pubspec.yaml 与三方库
### 2.1 MacBook Pro 端的核心原则
> **MacBook Pro 端不需要 `packages/` 目录,直接使用远程三方库即可。**
项目 `pubspec.yaml` 中的本地包引用(`path: packages/xxx`)是为鸿蒙端准备的。
MacBook Pro 端使用官方 Flutter SDK需要将这些本地包引用替换为远程版本号。
**为什么不能直接用本地包?**
本地包中包含 `TargetPlatform.ohos` 引用鸿蒙SDK新增的枚举值官方 SDK 没有此值,会导致编译报错:
```
Error: The getter 'ohos' isn't defined for the class 'TargetPlatform'
```
受影响的本地包有 5 个:
| 包名 | 引用次数 | 引用类型 |
|---|---|---|
| flex_color_picker | 2 | `case TargetPlatform.ohos:` (switch) |
| flutter_quill | 2 | `case TargetPlatform.ohos:` (switch) |
| flutter_local_notifications | 8 | `== TargetPlatform.ohos` (if比较) |
| mobile_scanner | 3 | `== / != TargetPlatform.ohos` (if比较) |
| audioplayers | 1 | `!= TargetPlatform.ohos` (if比较) |
**解决方案**MacBook Pro 端使用远程版本,远程版本不含 `TargetPlatform.ohos`,编译正常。
### 2.2 MacBook Pro 端 pubspec.yaml 修改指南
克隆项目后,需要修改 `pubspec.yaml`,将本地包引用替换为远程版本号。
#### 2.2.1 dependencies 区域 — 需要替换的包
将以下包从 `path: packages/xxx` 改为版本号:
```yaml
# ❌ 原始写法(鸿蒙端)
shared_preferences:
path: packages/shared_preferences
# ✅ MacBook Pro 端改为远程版本
shared_preferences: ^2.5.5
```
**完整替换清单:**
| 包名 | 远程版本号 | 说明 |
|---|---|---|
| shared_preferences | ^2.5.5 | 轻量KV持久化 |
| flutter_secure_storage | ^10.2.0 | 加密安全存储 |
| hive_flutter | ^1.1.0 | Hive Flutter适配 |
| path_provider | ^2.1.5 | 系统目录路径获取 |
| package_info_plus | ^10.1.0 | 应用包信息读取 |
| connectivity_plus | ^7.1.1 | 网络连接状态监听 |
| device_info_plus | ^13.1.0 | 设备硬件信息读取 |
| permission_handler | ^12.0.1 | 运行时权限请求 |
| flutter_local_notifications | ^21.0.0 | 本地推送通知 |
| url_launcher | ^6.3.2 | 打开外部URL/应用 |
| app_links | ^7.0.0 | 深度链接处理 |
| home_widget | ^0.9.1 | iOS/Android桌面小组件 |
| file_picker | ^11.0.0 | 文件选择器(⚠️ API变更见§2.5 |
| image_picker | ^1.2.2 | 相机/相册选图 |
| share_plus | ^13.1.0 | 系统分享面板 |
| gal | ^2.3.0 | 保存图片/视频到相册 |
| pro_image_editor | ^12.4.4 | 图片编辑器核心(⚠️ 见§2.5 |
| flutter_quill | ^11.5.0 | Quill富文本编辑器 |
| flex_color_picker | ^3.8.0 | HSL颜色选择器 |
| flutter_image_compress | ^2.4.0 | 图片压缩 |
| wakelock_plus | ^1.4.0 | 屏幕常亮控制 |
| audioplayers | ^6.5.0 | 音频播放 |
| record | ^6.0.0 | 录音 |
| video_compress | ^3.1.2 | 视频压缩 |
| video_player | ^2.10.0 | 视频播放 |
| local_auth | ^3.0.1 | 生物识别认证 |
| sensors_plus | ^6.1.0 | 加速度传感器 |
| battery_plus | ^7.0.0 | 电池状态监听 |
| network_info_plus | ^8.1.0 | WiFi网络信息 |
| flutter_webrtc | ^1.4.0 | WebRTC音视频通信 |
| flutter_blue_plus | ^2.1.0 | 蓝牙BLE通信 |
| flutter_nfc_kit | ^3.6.0 | NFC读写 |
| mobile_scanner | ^7.1.4 | 二维码/条形码扫描 |
| wifi_iot | ^0.3.19 | WiFi IoT设备连接 |
| nearby_service | ^0.2.1 | 近场设备发现+通信 |
| sqflite | ^2.4.1 | SQLite轻量数据库 |
| receive_sharing_intent | git引用 | 接收外部分享内容(⚠️ gitcode引用见§2.5 |
| workmanager | ^0.9.0 | 后台任务调度 |
| flutter_tts | ^4.2.0 | TTS文本转语音朗读 |
| speech_to_text | ^7.0.0 | 语音转文字 |
| live_activities | ^2.0.0 | 灵动岛/实时活动 |
| flutter_vibrate | git引用 | 跨平台触觉反馈(⚠️ gitcode引用见§2.5 |
| bitsdojo_window | - | ❌ 已移除,替换为 window_manager |
| window_manager | ^0.5.1 | 桌面端窗口管理(替代 bitsdojo_window |
#### 2.2.2 dependency_overrides 区域 — 整体替换
MacBook Pro 端不需要 `dependency_overrides` 中的本地包覆盖,改为仅保留版本号覆盖:
```yaml
# MacBook Pro 端的 dependency_overrides精简版
dependency_overrides:
meta: ^1.17.0
web: ^1.1.0
timezone: ^0.11.0
win32: ^6.0.1
# 删除所有 path: packages/xxx 条目
```
#### 2.2.3 快速替换脚本
```bash
# 在项目根目录执行,自动将本地包引用替换为远程版本
# ⚠️ 执行前请备份 pubspec.yaml
# 方式1手动替换推荐更可控
# 用编辑器打开 pubspec.yaml搜索 "path: packages/" 逐个替换
# 方式2使用 sed 批量替换macOS 终端)
# 将所有 "path: packages/xxx" 行替换为对应版本号
# 注意:此脚本仅作参考,请根据实际版本号调整
```
#### 2.2.4 ⚠️ 重要:不要提交修改后的 pubspec.yaml
```bash
# 修改 pubspec.yaml 后,使用 git stash 暂存,不要提交
git stash push -m "macOS-local-pubspec" pubspec.yaml
# 需要恢复时
git stash pop
# 或者将修改后的 pubspec.yaml 加入 .git/info/exclude
echo "pubspec.yaml" >> .git/info/exclude
```
> **铁律**MacBook Pro 端对 `pubspec.yaml` 的修改**绝对不能提交到 Git**。
> 仓库中的 `pubspec.yaml` 必须保持鸿蒙端的本地包引用配置。
### 2.3 已迁移至远程版本的纯Dart包
以下包已从本地包迁移为远程版本依赖,两端无需额外操作:
```
badges ^3.2.0 | catcher_2 ^2.1.9 | flutter_card_swiper ^7.2.0
stupid_simple_sheet ^0.9.1+1 | liquid_glass_easy ^1.1.1
liquid_glass_widgets ^0.11.0 | flutter_shaders_ui ^0.1.0
flutter_spritesheet_animation ^1.0.1 | image_size_getter ^2.4.1
extended_image ^10.0.1 | photo_view ^0.15.0
```
### 2.4 MacBook Pro 端完整操作流程
```bash
# 1. 克隆仓库
git clone <仓库URL> xianyan
cd xianyan
# 2. 修改 pubspec.yaml替换本地包为远程版本
# 参见 §2.2 的替换清单
# 3. 获取依赖
flutter pub get
# 4. 编译验证
flutter build ios --no-codesign
flutter build macos
# 6. 防止误提交 pubspec.yaml
git stash push -m "macOS-local-pubspec" pubspec.yaml
# 或
echo "pubspec.yaml" >> .git/info/exclude
```
### 2.5 特殊包说明
#### 2.5.1 pro_image_editor已迁移至远程版本
`pro_image_editor` 已从本地包迁移为远程版本 `^12.4.4`MacBook Pro 端直接使用远程版本即可:
```yaml
# MacBook Pro 端使用远程版本
pro_image_editor: ^12.4.4
```
> **注意**:如果项目代码中使用了自定义的 `CanvasStyleModel` 类,
> 远程版本可能不包含此类型,需要检查兼容性。
> 如遇编译错误,可恢复使用本地包版本(`path: packages/pro_image_editor`)。
#### 2.5.2 file_pickerAPI 变更)
`file_picker ^11.0.0` 的 API 发生了变更:
```dart
// ❌ 旧版 APIfile_picker ^8.x
final result = await FilePicker.platform.pickFiles();
// ✅ 新版 APIfile_picker ^11.x
final result = await FilePicker.pickFiles();
```
项目代码已更新为新版 API。鸿蒙端如使用本地包版本`file_picker ^8.x`
需注意 API 差异,或升级本地包到 `^11.x`
#### 2.5.3 flutter_secure_storage版本升级
`flutter_secure_storage ^10.2.0` 的 Windows 平台实现兼容 `win32 ^6.0.1`
解决了之前版本与 `win32 6.x` 的编译冲突。
#### 2.5.4 receive_sharing_intentgitcode 引用)
`receive_sharing_intent` 在 pub.dev 上的版本与鸿蒙端不兼容MacBook Pro 端需使用 gitcode 引用:
```yaml
# MacBook Pro 端使用 gitcode 引用
receive_sharing_intent:
git:
url: "https://gitcode.com/openharmony-sig/fluttertpc_receive_sharing_intent.git"
ref: "br_v1.8.1_ohos"
```
> **注意**gitcode 版本的 `SharedMediaFile` 构造函数可能包含 `ohosPath` 等鸿蒙特有参数,
> 官方 SDK 不存在这些参数。项目代码中已通过 `pu.isOhos` 条件分支隔离。
#### 2.5.5 flutter_vibrategitcode 引用)
`flutter_vibrate` 在 pub.dev 上的版本不支持鸿蒙MacBook Pro 端需使用 gitcode 引用:
```yaml
# MacBook Pro 端使用 gitcode 引用
flutter_vibrate:
git:
url: https://gitcode.com/openharmony-sig/fluttertpc_flutter_vibrate.git
```
#### 2.5.6 home_widgetpub.dev 远程版本)
`home_widget` 的 gitcode 版本依赖 `path_provider` 的 git 版本,会与远程 `path_provider` 冲突。
MacBook Pro 端使用 pub.dev 版本 `^0.9.1`,鸿蒙端的 `ohosName` 参数通过 `pu.isOhos` + `dynamic` 调用隔离:
```yaml
# MacBook Pro 端使用 pub.dev 远程版本
home_widget: ^0.9.1
```
---
## 三、Git 提交与合并规范
### 3.1 分支策略
```
main (受保护) ← 所有平台共用
├── feature/xxx ← 功能开发(所有平台共用)
├── fix/xxx ← Bug修复
└── hotfix/xxx ← 紧急修复
```
> **不需要按平台创建长期分支**。`lib/` 代码所有平台共用,独立平台分支会导致大量合并冲突。
> 平台原生代码已天然隔离(`ios/`、`macos/`、`ohos/` 各自独立),不会互相污染。
### 3.2 iOS/macOS 开发者提交规则
**✅ 应该提交的文件:**
- `lib/` 目录下的所有 Dart 代码
- `ios/` 目录下的原生代码
- `macos/` 目录下的原生代码
- `assets/` 目录下的资源文件
- `test/` 目录下的测试代码
**❌ 不要提交的文件:**
- `pubspec.yaml`MacBook Pro 端已替换为远程版本,**绝不能提交**
- `packages/` 目录(已在 `.gitignore` 中排除)
- `ohos/` 目录下的鸿蒙原生代码
- 鸿蒙SDK特有的配置文件
**⚠️ pubspec.yaml 提交铁律:**
1. **MacBook Pro 端修改的 `pubspec.yaml` 绝对不能提交** — 仓库中的版本必须保持鸿蒙端本地包引用
2. **使用 `git stash` 或 `.git/info/exclude` 隔离修改** — 防止误提交
3. **如果必须提交 `pubspec.yaml`**(如新增了远程依赖),先 `git stash pop` 恢复原始版本,在原始版本上修改,再提交
### 3.3 pubspec.yaml 处理策略(⭐ 重点)
由于 MacBook Pro 端和鸿蒙端使用不同的 `pubspec.yaml` 配置,需要特别注意。
#### 3.3.1 两端 pubspec.yaml 差异
| 区域 | 鸿蒙端(仓库版本) | MacBook Pro 端(本地版本) |
|---|---|---|
| dependencies 中的本地包 | `path: packages/xxx` | 远程版本号(如 `^2.5.5` |
| dependency_overrides | 包含所有 `path: packages/xxx` | 仅保留 `meta``web` 等版本号覆盖 |
#### 3.3.2 MacBook Pro 端日常操作
```bash
# 开发前:恢复 MacBook Pro 本地版本
git stash list # 查看暂存
git stash pop # 恢复修改后的 pubspec.yaml
# 开发中:正常编码,不涉及 pubspec.yaml 的提交
# 提交代码时:先暂存本地 pubspec.yaml
git stash push -m "macOS-local-pubspec" pubspec.yaml
git add lib/ ios/ macos/ assets/
git commit -m "feat: xxx"
git push origin feature/xxx
# 提交后:恢复本地 pubspec.yaml
git stash pop
```
#### 3.3.3 需要新增依赖时
MacBook Pro 端新增依赖时,需要在**两端**分别操作:
```bash
# ── MacBook Pro 端 ──
# 1. 在本地 pubspec.yaml 中添加新依赖
echo " new_package: ^1.0.0" >> pubspec.yaml
flutter pub get
# 2. 恢复仓库版本的 pubspec.yaml
git stash push -m "macOS-local-pubspec" pubspec.yaml
git stash pop # 如果之前有暂存,先恢复
# 3. 在仓库版本的 pubspec.yaml 中也添加新依赖
# (保持鸿蒙端的本地包引用格式)
# 4. 提交仓库版本
git add pubspec.yaml
git commit -m "feat: add new_package dependency"
# ── 通知鸿蒙开发者 ──
# 告知新增了 new_package评估是否需要鸿蒙适配
# 如果需要适配 → 鸿蒙端添加本地包引用
# 如果不需要适配 → 两端都使用远程版本
```
#### 3.3.4 git pull 后 pubspec.yaml 被覆盖
```bash
# git pull 后,仓库版本的 pubspec.yaml 覆盖了本地修改
# 重新替换为远程版本即可:
# 方式1从备份恢复
git stash pop # 如果之前有暂存
# 方式2重新手动替换参见 §2.2
# 搜索 "path: packages/" 逐个替换为远程版本号
```
#### 3.3.5 减少冲突的最佳实践
| 做法 | 说明 |
|---|---|
| **MacBook Pro 端不提交 pubspec.yaml** | 从根本上避免冲突 |
| **使用 git stash 隔离** | 每次提交前 stash提交后 pop |
| **新增依赖时通知鸿蒙开发者** | 让鸿蒙端同步评估适配 |
| **版本号升级单独提交** | 不要和功能代码混在一起提交 |
### 3.4 其他合并注意事项
1. **不要删除 `pu.isOhos` 相关代码**:这些条件分支在 iOS/macOS 上不会执行,但删除会导致鸿蒙端编译失败
2. **不要修改 `OhosAppShell`、`OhosNavBridge` 等鸿蒙专用类**:这些类仅在鸿蒙端使用
3. **新增页面路由时**:需同时在 `app_router.dart`GoRouter路由表`ohos_nav_bridge.dart`(鸿蒙路由映射表)中注册
### 3.5 PR 审查要点
- [ ] 未提交 MacBook Pro 端修改的 `pubspec.yaml`(仓库版本保持鸿蒙本地包引用)
- [ ] 未引入 `TargetPlatform` exhaustive switch 问题
- [ ] 新增路由已在 `ohos_nav_bridge.dart` 中同步
- [ ] `lib/` 代码无平台特定硬编码(应使用 `platform_utils.dart`
- [ ] 新增依赖已通知鸿蒙开发者评估适配
---
## 四、TargetPlatform.ohos 处理
### 4.1 问题背景
鸿蒙定制 Flutter SDK 在 `TargetPlatform` 枚举中新增了 `TargetPlatform.ohos`
官方 SDK 不包含此值。本地包中引用了 `TargetPlatform.ohos`,在官方 SDK 下会编译报错。
**MacBook Pro 端的解决方案**:使用远程版本的三方库,远程版本不含 `TargetPlatform.ohos`,无需关心此问题。
### 4.2 lib/ 代码中的平台判断
`lib/` 目录下的项目代码使用 `platform_utils.dart` 进行平台判断,**不依赖 `TargetPlatform.ohos` 枚举**
在官方 SDK 下编译完全正常:
```dart
// lib/ 代码使用 Platform.operatingSystem 字符串比较,不依赖枚举
// platform_io_native.dart:
bool _isOhos() {
try {
return Platform.operatingSystem == 'ohos'; // 字符串比较官方SDK也支持
} catch (_) {
return false;
}
}
```
### 4.3 iOS/macOS 开发者规范
**规则1不要使用 `switch(TargetPlatform)` 穷举匹配**
```dart
// ❌ 错误 — 官方SDK没有 ohos鸿蒙SDK缺少 ohos 会报错
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
// ...
case TargetPlatform.android:
// ...
case TargetPlatform.macOS:
// ...
case TargetPlatform.windows:
// ...
case TargetPlatform.linux:
// ...
case TargetPlatform.fuchsia:
// ...
}
// ✅ 正确 — 使用 if-else 或添加 default
if (defaultTargetPlatform == TargetPlatform.iOS) {
// iOS 逻辑
} else if (defaultTargetPlatform == TargetPlatform.macOS) {
// macOS 逻辑
} else {
// 其他平台
}
// ✅ 正确 — switch 加 default
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
case TargetPlatform.android:
return mobileLayout;
default:
return desktopLayout;
}
```
**规则2使用 `platform_utils.dart` 判断平台**
```dart
import 'package:xianyan/core/utils/platform_utils.dart' as pu;
// ✅ 推荐方式 — 内部使用字符串比较,两端都安全
if (pu.isIOS) { /* iOS */ }
if (pu.isMacOS) { /* macOS */ }
if (pu.isOhos) { /* 鸿蒙 */ }
if (pu.isMobile) { /* 移动端 */ }
if (pu.isDesktop) { /* 桌面端 */ }
```
### 4.4 已知的 TargetPlatform.ohos 适配点(仅本地包)
以下文件在本地包中引用了 `TargetPlatform.ohos`MacBook Pro 端使用远程版本不受影响:
| 文件 | 位置 | 引用类型 |
|---|---|---|
| `packages/flex_color_picker/.../picker_functions.dart` | L49, L65 | `case TargetPlatform.ohos:` |
| `packages/flutter_quill/.../raw_editor_state.dart` | L309 | `case TargetPlatform.ohos:` |
| `packages/flutter_quill/.../link.dart` | L58 | `case TargetPlatform.ohos:` |
| `packages/flutter_local_notifications/.../plugin.dart` | 8处 | `== TargetPlatform.ohos` |
| `packages/mobile_scanner/.../method_channel.dart` | 3处 | `== / != TargetPlatform.ohos` |
| `packages/audioplayers/.../audioplayer.dart` | L178 | `!= TargetPlatform.ohos` |
> 以上文件均在 `packages/` 目录中MacBook Pro 端使用远程版本,不会编译这些文件。
### 4.5 lib/ 代码中的鸿蒙SDK类型桥接
鸿蒙端本地包中某些类有官方 SDK 不存在的额外参数或类型(如 `OhosInitializationSettings``ohosName`)。
项目通过桥接文件和 `dynamic` 调用隔离这些差异,确保两端编译正常。
#### 4.5.1 通知服务桥接
**桥接文件**`lib/core/services/notification/notification_init_stub.dart`
| 方法 | 官方SDK行为 | 鸿蒙端行为 |
|---|---|---|
| `buildNotificationInitSettings()` | 构建 `InitializationSettings`(无 ohos 参数) | 鸿蒙端本地包的 `InitializationSettings` 自带 ohos 参数,官方端不传即可 |
| `requestOhosNotificationPermission()` | 返回 `false`(不执行) | 动态调用 `OhosFlutterLocalNotificationsPlugin` |
**使用此桥接的文件**
- `lib/core/services/notification/notification_service.dart`
- `lib/core/services/notification/local_notification_service.dart`
- `lib/features/file_transfer/services/notification_service.dart`
#### 4.5.2 HomeWidget 桥接
鸿蒙端本地包的 `HomeWidget.updateWidget()``HomeWidget.requestPinWidget()``ohosName` 参数,
官方 SDK 不存在此参数。项目通过 `pu.isOhos` 条件 + `dynamic` 调用隔离:
```dart
// 官方SDK标准调用
await HomeWidget.updateWidget(
androidName: type.androidProviderName,
iOSName: type.iosWidgetKind,
);
// 鸿蒙端dynamic 调用,传入 ohosName
if (pu.isOhos) {
final dynamic updateWidget = HomeWidget.updateWidget;
await updateWidget(
androidName: type.androidProviderName,
iOSName: type.iosWidgetKind,
ohosName: type.ohosFormName,
);
}
```
**涉及文件**
- `lib/core/services/data/home_widget_service.dart`
- `lib/features/widget/providers/widget_provider.dart`
#### 4.5.3 新增鸿蒙SDK特有类型的规范
如果鸿蒙端本地包新增了官方 SDK 不存在的类型或参数,按以下规范处理:
1. **在 `lib/` 代码中不直接 import 鸿蒙专用类型**(如 `OhosInitializationSettings`
2. **使用 `pu.isOhos` 条件分支**:鸿蒙端逻辑仅在 `pu.isOhos` 为 true 时执行
3. **使用 `dynamic` 调用**:绕过官方 SDK 的静态类型检查
4. **优先创建桥接文件**:将鸿蒙特有逻辑封装在独立文件中(如 `notification_init_stub.dart`
---
## 五、其他注意事项
### 5.1 应用入口架构差异
项目在 `app.dart` 中根据平台选择不同的应用架构:
| 平台 | 应用架构 | 导航方式 | 入口Widget |
|---|---|---|---|
| iOS/macOS/Android | `MaterialApp.router` + GoRouter | GoRouter 声明式路由 | `AppShell` |
| 鸿蒙 | `MaterialApp(home:)` + Navigator | `CupertinoTabView` + Navigator.push | `OhosAppShell` |
**原因**:鸿蒙端 `MaterialApp.router` 白屏,无法使用 GoRouter因此使用传统 Navigator 导航。
### 5.2 路由注册双写
新增页面时,必须在两处注册路由:
1. **`lib/core/router/app_router.dart`** — GoRouter 路由表iOS/macOS/Android 使用)
2. **`lib/core/router/ohos_nav_bridge.dart`** — 鸿蒙路由映射表
```dart
// app_router.dart
GoRoute(
path: AppRoutes.newPage,
name: 'new-page',
parentNavigatorKey: rootNavigatorKey,
pageBuilder: (context, state) =>
iosSlideTransition(state: state, child: const NewPage()),
),
// ohos_nav_bridge.dart
AppRoutes.newPage: (_) => const NewPage(),
```
### 5.3 平台特性检测
使用 `OhosDeviceCapabilities` 检测鸿蒙设备特性(毛玻璃、液态玻璃、重度动画、折叠屏等),
iOS/macOS 端这些检测不会执行(`isOhos` 为 false无需关心。
### 5.4 packages 目录说明
- `packages/` 目录存放鸿蒙适配的本地三方库,已在 `.gitignore` 中排除
- MacBook Pro 端需要 `packages/pro_image_editor/`(含魔改的 `CanvasStyleModel`),从 zip 解压获取
- 其他本地包 MacBook Pro 端使用远程版本,无需放在 `packages/` 目录
- 鸿蒙开发者需手动维护本地 `packages/` 目录
### 5.5 MacBook Pro 修改 ios/macos 后,鸿蒙端是否需要同步?
| 修改内容 | 鸿蒙端是否需要同步 | 原因 |
|---|---|---|
| `ios/` 目录 | ❌ 不需要 | 平台原生代码,鸿蒙不使用 |
| `macos/` 目录 | ❌ 不需要 | 平台原生代码,鸿蒙不使用 |
| `lib/` 目录 | ✅ 需要同步 | Dart 代码所有平台共用 |
| `pubspec.yaml` | ✅ 需要同步 | 依赖配置共享(鸿蒙端自行维护本地包版本) |
| `assets/` 目录 | ✅ 需要同步 | 资源文件共享 |
### 5.6 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| `flutter pub get` 报 packages/xxx 目录不存在 | pubspec.yaml 中有 `path: packages/xxx` 引用 | 替换为远程版本号,参见 §2.2 |
| 编译报 `TargetPlatform.ohos` 不存在 | 使用了含 ohos 引用的本地包 | 使用远程版本,参见 §2.1 |
| iOS 编译报 ohos 相关错误 | 误用鸿蒙SDK编译iOS | 切换到官方 Flutter SDK |
| GoRouter 路由正常但鸿蒙端白屏 | 鸿蒙端不支持 GoRouter | 检查 OhosNavBridge 路由映射 |
| git pull 后 pubspec.yaml 被覆盖 | 仓库版本是鸿蒙端配置 | 重新替换为远程版本,参见 §3.3.4 |
| 误提交了 MacBook Pro 端的 pubspec.yaml | 删除了鸿蒙本地包引用 | 立即回退,恢复鸿蒙端配置 |
| 新增依赖后鸿蒙端报错 | 新增的三方库未适配鸿蒙 | 通知鸿蒙开发者评估,必要时本地化到 packages/ |
| 编译报 `OhosInitializationSettings` 不存在 | 官方SDK无此类型 | 使用 `notification_init_stub.dart` 桥接,参见 §4.5 |
| 编译报 `ohosName` 参数不存在 | 官方SDK的 HomeWidget 无此参数 | 使用 `dynamic` 调用,参见 §4.5.2 |
| `pro_image_editor``CanvasStyleModel` 不存在 | 远程版本不含魔改内容 | 使用本地包 `path: packages/pro_image_editor`,参见 §2.5.1 |
| `FilePicker.platform` 报错 | file_picker 11.x API 变更 | 使用 `FilePicker.pickFiles()`,参见 §2.5.2 |
---
## 六、快速检查清单
MacBook Pro 开发前,确认以下事项:
- [ ] 使用官方 Flutter SDK非 flutter-ohos
- [ ]`git clone` 拉取最新代码
- [ ] 已将 `pubspec.yaml` 中的本地包替换为远程版本(参见 §2.2
- [ ] 已解压 `pro_image_editor``packages/` 目录(参见 §2.5.1
- [ ] `flutter pub get` 无报错
- [ ] `dart analyze lib/` 无 error
- [ ] 新增代码未使用 `switch(TargetPlatform)` 穷举匹配
- [ ] 新增鸿蒙SDK特有类型已通过桥接文件隔离参见 §4.5
- [ ] 新增路由已在 `app_router.dart``ohos_nav_bridge.dart` 双写
- [ ] 已使用 `git stash` 隔离本地 `pubspec.yaml`,不会误提交
- [ ] Git 提交未删除 `pu.isOhos` 相关代码
---
*文档创建时间: 2026-05-21 | 更新时间: 2026-05-22 v3 | 维护者: 闲言APP开发团队*