# MynaTalk iOS App（八哥口语 iOS 版）

iOS 端与 [android/](../android/README.md) 示例 App 功能对齐的移动端：

- 在线视频目录（`GET /api/v1/videos`，仅展示 `ready` 课程，自动解析相对流地址）
- AVPlayer 在线播放 + 本地缓存导入；单击播放/暂停
- 左划 / 右划：上一句 / 下一句（无句边界时回退为 10 秒快退 / 快进）
- 长按播放区：按触摸点水平位置变速（左慢右快，0.5x - 2.0x），松手恢复原速
- 按句跳转：句边界来自 `GET /api/v1/videos/{sha256}/sentence-boundaries`
- 连续播放开关：关闭时循环播放当前句子，开启时按句子顺序连续播放
- 进度条拖动定位、播放状态 / 句号 / 变速显示
- 横屏全屏播放（半透明句面板，与安卓端横屏布局一致）
- 本地视频导入：复制到缓存并计算 SHA-256，自动匹配服务端句边界
- 朗读评测：麦克风录音（AAC 16kHz），上传
  `POST /api/v1/videos/{sha256}/sentences/{index}/assessments`，
  展示内容 / 流畅度 / 时长 / 停顿 / 语速等分数与漏读、多读、反馈
- HTTPS 因 TLS 问题失败时自动降级重试 HTTP（与安卓端 `allowHttpFallback` 一致）

## 目录结构

```
ios/
├── OralTrainer.xcodeproj        # Xcode 工程
└── OralTrainer/
    ├── Config.swift             # 服务端地址与评测密钥（改这里）
    ├── Models/                  # 课程 / 句边界 / 评测数据模型
    ├── Services/                # HTTP 客户端、课程目录、句边界、评测上传
    ├── Player/                  # 播放控制器（AVPlayer）+ 手势播放区
    └── Views/                   # SwiftUI 界面（训练 / 测试 / 全屏）
```

## 构建与运行

1. 需要 macOS + Xcode（16 或更新版本），iOS 部署目标 16.0。
2. 打开 `ios/OralTrainer.xcodeproj`，在 Signing 里选择你的开发者团队。
3. 选一台 iPhone / iPad 或模拟器运行；真机评测录音需要麦克风权限
   （首次点击“开始录音”时会自动请求）。
4. 本机没有 Xcode 时，也可在另一台装有 Xcode 的 Mac 上打开本目录构建。

## 配置

- 服务端地址：改 `OralTrainer/Config.swift` 里的 `serverBaseURL`
  （内网可填 `http://<服务器IP>:<端口>`）。
- 评测密钥：改 `assessmentAPIKey`，填服务器 `sentence_api/.env` 里的
  `CLIENT_API_KEY`；安卓端示例 App 用的是同一个密钥。
- 生产环境建议保持 HTTPS；`Info.plist` 中的 `NSAllowsArbitraryLoads`
  与安卓端的明文 HTTP 开关一样，仅为内网/私有部署提供便利。

## 与安卓端的差异说明

- 播放内核为系统 AVPlayer（对应安卓 Media3/ExoPlayer），支持 MP4/MOV/M4V
  及 HLS；MKV/WEBM 需先转码，与 iOS 系统播放器能力一致。
- 横屏全屏：点播放区右下角的旋转按钮进入；iPhone 会自动锁定横屏，
  退出后恢复竖屏；iPad 允许全部方向。
- 速度胶囊支持点击循环 1x → 1.25x → 1.5x → 1.75x → 2.0x
  （安卓端只有长按变速，这里作为 iOS 便捷补充）。

## 常见问题

- “云端暂不可用：…”：检查手机能否访问服务端、地址是否填对、网关证书是否有效。
- 本地视频评测提示“仅云端课程支持朗读评测”：本地文件需先通过管理端上传到服务器。
- 录音提示“无法开始录制”：录音已改用 `AVAudioEngine` 采集并转码 AAC 16kHz
  （`AVAudioRecorder` 在 iOS 26 真机上存在 `record()` 恒返回 `false` 的已知问题）。
  若仍失败，真机请确认 设置 → 隐私与安全性 → 麦克风 已允许本 App 使用麦克风，
  且没有其他 App 正在占用麦克风；模拟器请先在 I/O → Audio Input 中选择输入设备
  （如 Mac 内置麦克风），并允许“模拟器”使用 Mac 麦克风。
- 配音“合成失败”：iOS 26 / macOS 26 上 `AVAssetExportSession` 导出纯音频会失败
  （AVError -11800，底层 `'fmt?'`），`AVAudioFile` 读回 AAC 也会报 `'fmt?'`。
  配音合成已改为合并录音时保留的原始 PCM（caf）后直接编码 AAC 16kHz，与录音转码
  同链路；如仍失败，提示中会附带底层错误详情，可按详情排查。
