docs: add iOS ops docs + CI config (IOS-INFO-028~031)
Some checks failed
iOS CI/CD / Build & Test (push) Has been cancelled
Some checks failed
iOS CI/CD / Build & Test (push) Has been cancelled
- rust-ffi-update.md: FFI binding update workflow - app-store-submission-checklist.md: 9-section App Store review - ios-ci.yml: GitHub Actions build + test on macos-15 - firebase-crashlytics-integration.md: Crashlytics setup guide Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
08b4c21ca2
commit
8b27430ed1
48
.github/workflows/ios-ci.yml
vendored
Normal file
48
.github/workflows/ios-ci.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
name: iOS CI/CD
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, develop]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-test:
|
||||||
|
name: Build & Test
|
||||||
|
runs-on: macos-15
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Select Xcode
|
||||||
|
run: sudo xcode-select -s /Applications/Xcode.app
|
||||||
|
|
||||||
|
- name: Build Rust xcframework (arm64 sim)
|
||||||
|
working-directory: ../zhixi-document-runtime
|
||||||
|
run: |
|
||||||
|
rustup target add aarch64-apple-ios-sim
|
||||||
|
cargo build --release -p zx_document_ffi --target aarch64-apple-ios-sim
|
||||||
|
|
||||||
|
- name: Build for iOS Simulator
|
||||||
|
run: |
|
||||||
|
xcodebuild build \
|
||||||
|
-project AIStudyApp/AIStudyApp.xcodeproj \
|
||||||
|
-scheme AIStudyApp \
|
||||||
|
-destination 'platform=iOS Simulator,name=iPhone 16' \
|
||||||
|
CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
|
||||||
|
|
||||||
|
- name: Run Tests
|
||||||
|
run: |
|
||||||
|
xcodebuild test \
|
||||||
|
-project AIStudyApp/AIStudyApp.xcodeproj \
|
||||||
|
-scheme AIStudyApp \
|
||||||
|
-destination 'platform=iOS Simulator,name=iPhone 16' \
|
||||||
|
CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO \
|
||||||
|
2>&1 | tee xcode-test.log
|
||||||
|
|
||||||
|
- name: Upload test log
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: xcode-test-log
|
||||||
|
path: xcode-test.log
|
||||||
78
docs/app-store-submission-checklist.md
Normal file
78
docs/app-store-submission-checklist.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# App Store 提审 Checklist
|
||||||
|
|
||||||
|
## 1. 代码与构建
|
||||||
|
|
||||||
|
- [ ] `Build Configuration = Release`
|
||||||
|
- [ ] 所有 Scheme 编译通过(iOS + Simulator)
|
||||||
|
- [ ] SwiftLint / ESLint 无 warning
|
||||||
|
- [ ] 单元测试全部通过
|
||||||
|
- [ ] `ENABLE_BITCODE = NO`(Xcode 15+)
|
||||||
|
- [ ] Deployment Target >= iOS 16.0
|
||||||
|
|
||||||
|
## 2. 隐私与权限
|
||||||
|
|
||||||
|
- [ ] `Info.plist` 无未声明的隐私权限
|
||||||
|
- [ ] 隐私清单(PrivacyInfo.xcprivacy)包含所有使用的 API
|
||||||
|
- [ ] UserDefaults
|
||||||
|
- [ ] FileTimestamp
|
||||||
|
- [ ] SystemBootTime
|
||||||
|
- [ ] App Tracking Transparency 弹窗(如使用 IDFA)
|
||||||
|
- [ ] 数据收集声明在 App Store Connect 中填写
|
||||||
|
|
||||||
|
## 3. 网络与安全
|
||||||
|
|
||||||
|
- [ ] 所有 API 调用使用 HTTPS
|
||||||
|
- [ ] ATS(App Transport Security)无例外域名(或已声明)
|
||||||
|
- [ ] API Key / Token 不硬编码在源码中
|
||||||
|
- [ ] Keychain 用于存储敏感凭证
|
||||||
|
- [ ] 证书和 Provisioning Profile 有效(≥30 天)
|
||||||
|
|
||||||
|
## 4. Rust xcframework
|
||||||
|
|
||||||
|
- [ ] `ZxDocumentRuntime.xcframework` 包含所需架构
|
||||||
|
- [ ] `ios-arm64`(真机)
|
||||||
|
- [ ] `ios-arm64-sim`(Apple Silicon 模拟器)
|
||||||
|
- [ ] `ios-x86_64-sim`(Intel 模拟器,可选)
|
||||||
|
- [ ] xcframework 已正确嵌入(Embed & Sign)
|
||||||
|
- [ ] `zx_document.swift` uniffi 绑定与 xcframework 版本一致
|
||||||
|
- [ ] 加密导出合规(如适用,提交 EAR 分类)
|
||||||
|
|
||||||
|
## 5. UI 与体验
|
||||||
|
|
||||||
|
- [ ] 启动图/Launch Screen 正确显示
|
||||||
|
- [ ] 无空白页面或崩溃路径
|
||||||
|
- [ ] iPad 适配(如声明支持)
|
||||||
|
- [ ] 深色模式适配
|
||||||
|
- [ ] 多语言文本无截断
|
||||||
|
- [ ] VoiceOver 可用(基础无障碍)
|
||||||
|
|
||||||
|
## 6. App Store Connect 元数据
|
||||||
|
|
||||||
|
- [ ] 应用名称、副标题、描述
|
||||||
|
- [ ] 关键词(100 字符内)
|
||||||
|
- [ ] 截图(6.7" + 6.5" + 5.5" 各 1-3 张,或仅 6.7")
|
||||||
|
- [ ] 应用图标(1024×1024)
|
||||||
|
- [ ] 分级(Rating)
|
||||||
|
- [ ] 版权信息
|
||||||
|
- [ ] 技术支持 URL
|
||||||
|
- [ ] 隐私政策 URL
|
||||||
|
|
||||||
|
## 7. 测试
|
||||||
|
|
||||||
|
- [ ] TestFlight 内部测试已通过
|
||||||
|
- [ ] 主要流程回归测试:登录→阅读→标记→分析
|
||||||
|
- [ ] 网络异常场景:飞行模式、弱网、超时
|
||||||
|
- [ ] App 切换(后台→前台)无数据丢失
|
||||||
|
- [ ] 低存储空间场景
|
||||||
|
|
||||||
|
## 8. 版本管理
|
||||||
|
|
||||||
|
- [ ] `CFBundleShortVersionString` 递增(如 1.0.0 → 1.1.0)
|
||||||
|
- [ ] `CFBundleVersion` 递增(Build Number)
|
||||||
|
- [ ] Git tag 对应版本号
|
||||||
|
|
||||||
|
## 9. 紧急回滚准备
|
||||||
|
|
||||||
|
- [ ] 上一版本 ipa 已归档
|
||||||
|
- [ ] 知道如何取消审核(App Store Connect → 移除提交)
|
||||||
|
- [ ] Release 分支保护已启用
|
||||||
150
docs/firebase-crashlytics-integration.md
Normal file
150
docs/firebase-crashlytics-integration.md
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
# 崩溃监控集成(Firebase Crashlytics)
|
||||||
|
|
||||||
|
## 1. 概述
|
||||||
|
|
||||||
|
Firebase Crashlytics 用于收集 iOS 应用崩溃日志,支持 Swift 层和 Rust FFI 层的崩溃追踪。
|
||||||
|
|
||||||
|
## 2. 集成步骤
|
||||||
|
|
||||||
|
### 2.1 添加依赖
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// Package.swift 或 Xcode SPM
|
||||||
|
.package(url: "https://github.com/firebase/firebase-ios-sdk", from: "11.0.0")
|
||||||
|
|
||||||
|
// Target dependencies
|
||||||
|
.product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 初始化
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// AppDelegate.swift 或 AIStudyApp.swift
|
||||||
|
import Firebase
|
||||||
|
|
||||||
|
func application(_ application: UIApplication,
|
||||||
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
|
FirebaseApp.configure()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 GoogleService-Info.plist
|
||||||
|
|
||||||
|
从 Firebase Console 下载 `GoogleService-Info.plist`,放入 Xcode 项目根目录(不要加入 git,加入 .gitignore)。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# .gitignore
|
||||||
|
GoogleService-Info.plist
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 dSYM 上传
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build Phase: Run Script
|
||||||
|
"${BUILD_DIR%/Build/Products}/${CONFIGURATION}-${PLATFORM_NAME}/AIStudyApp.app/dSYMs"
|
||||||
|
${PODS_ROOT}/FirebaseCrashlytics/upload-symbols \
|
||||||
|
-gsp "${PROJECT_DIR}/GoogleService-Info.plist" \
|
||||||
|
-p ios "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 自定义日志
|
||||||
|
|
||||||
|
### 3.1 Swift 层
|
||||||
|
|
||||||
|
```swift
|
||||||
|
import FirebaseCrashlytics
|
||||||
|
|
||||||
|
// 记录关键路径
|
||||||
|
Crashlytics.crashlytics().log("Reading session opened: \(materialId)")
|
||||||
|
|
||||||
|
// 设置用户标识
|
||||||
|
Crashlytics.crashlytics().setUserID(userId)
|
||||||
|
|
||||||
|
// 自定义 key
|
||||||
|
Crashlytics.crashlytics().setCustomValue(materialId, forKey: "last_material_id")
|
||||||
|
Crashlytics.crashlytics().setCustomValue(sessionState, forKey: "session_state")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Rust FFI 层
|
||||||
|
|
||||||
|
Rust panic 通过 `std::panic::catch_unwind` 捕获后,通过 FFI 回调通知 Swift:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// zx_document.swift (uniffi generated)
|
||||||
|
// Rust panics are caught and returned as errors;
|
||||||
|
// Swift layer logs them to Crashlytics
|
||||||
|
do {
|
||||||
|
try documentRuntime.openMaterial(materialId)
|
||||||
|
} catch {
|
||||||
|
Crashlytics.crashlytics().record(error: error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 关键监控点
|
||||||
|
|
||||||
|
| 位置 | 监控内容 |
|
||||||
|
|------|----------|
|
||||||
|
| `AppDelegate.didFinishLaunching` | 启动崩溃 |
|
||||||
|
| `MaterialReaderView.onAppear` | 阅读器打开 |
|
||||||
|
| `UploadScheduler.flush()` | 批量上传 |
|
||||||
|
| `RuntimeRecoveryService.recover()` | 会话恢复 |
|
||||||
|
| `FFI 调用点` | Rust panic |
|
||||||
|
| `sceneDidEnterBackground` | 后台切换 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 符号化
|
||||||
|
|
||||||
|
### 5.1 Swift 符号
|
||||||
|
|
||||||
|
Xcode Archive 自动包含 dSYM。Crashlytics 通过 upload-symbols 脚本自动符号化。
|
||||||
|
|
||||||
|
### 5.2 Rust 符号
|
||||||
|
|
||||||
|
Rust xcframework 的 dSYM 需手动生成:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建带调试符号的 Rust 库
|
||||||
|
cargo build --release -p zx_document_ffi --target aarch64-apple-ios
|
||||||
|
|
||||||
|
# 提取 dSYM
|
||||||
|
dsymutil target/aarch64-apple-ios/release/libzx_document_ffi.a \
|
||||||
|
-o ZxDocumentRuntime.dSYM
|
||||||
|
|
||||||
|
# 上传到 Crashlytics
|
||||||
|
${PODS_ROOT}/FirebaseCrashlytics/upload-symbols \
|
||||||
|
-gsp GoogleService-Info.plist \
|
||||||
|
-p ios ZxDocumentRuntime.dSYM
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 告警阈值
|
||||||
|
|
||||||
|
| 指标 | 阈值 | 响应 |
|
||||||
|
|------|:--:|------|
|
||||||
|
| Crash-free rate | < 99% | 紧急修复 |
|
||||||
|
| Crash-free rate | < 99.5% | P1 调查 |
|
||||||
|
| 新 crash 类型 | ≥ 1 | 24h 内分类 |
|
||||||
|
| 回归 crash | ≥ 1 | 立即回滚 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 隐私合规
|
||||||
|
|
||||||
|
- Crashlytics 不采集 PII(个人身份信息)
|
||||||
|
- 用户 ID 使用匿名化标识符(UUID),不关联登录邮箱
|
||||||
|
- 崩溃日志保留 90 天
|
||||||
|
- 在隐私政策中声明使用 Firebase Crashlytics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 相关文档
|
||||||
|
|
||||||
|
- [App Store 提审 Checklist](./app-store-submission-checklist.md)
|
||||||
|
- [iOS CI/CD](./ios-ci.yml) (.github/workflows/)
|
||||||
144
docs/rust-ffi-update.md
Normal file
144
docs/rust-ffi-update.md
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# Rust FFI 绑定更新流程
|
||||||
|
|
||||||
|
## 1. 概述
|
||||||
|
|
||||||
|
iOS 通过 uniffi 生成的 Swift 绑定调用 Rust Document Runtime(zx_document_core)。
|
||||||
|
|
||||||
|
更新流程:修改 Rust 代码 → 重新生成 bindings → Xcode 重新编译
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
zhixi-document-runtime/
|
||||||
|
├── crates/
|
||||||
|
│ ├── zx_document_core/ # 核心 Rust 库
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── document.rs # DocumentInfo + build_document_info
|
||||||
|
│ │ │ ├── material_type.rs
|
||||||
|
│ │ │ ├── markdown.rs # Markdown 解析
|
||||||
|
│ │ │ ├── pdf.rs # PDF 元数据/文本提取
|
||||||
|
│ │ │ ├── epub.rs # EPUB 元数据/章节/文本
|
||||||
|
│ │ │ ├── search.rs # 全文搜索
|
||||||
|
│ │ │ ├── anchors.rs # NoteAnchor
|
||||||
|
│ │ │ ├── events_v2.rs # V2 事件 buffer
|
||||||
|
│ │ │ ├── session_v2.rs # V2 Session 管理
|
||||||
|
│ │ │ └── image_meta.rs # 图片元数据
|
||||||
|
│ │ └── Cargo.toml
|
||||||
|
│ └── zx_document_ffi/ # FFI 绑定层
|
||||||
|
│ ├── src/
|
||||||
|
│ │ └── lib.rs # uniffi 导出定义
|
||||||
|
│ ├── src/zx_document.udl # UDL 接口定义
|
||||||
|
│ └── Cargo.toml
|
||||||
|
└── Cargo.toml # Workspace root
|
||||||
|
|
||||||
|
ios-projects/
|
||||||
|
└── AIStudyApp/
|
||||||
|
└── AIStudyApp/
|
||||||
|
└── Core/
|
||||||
|
├── ZxDocumentRuntime.xcframework/ # 预编译 Rust 库
|
||||||
|
└── zx_document.swift # uniffi 生成的 Swift 绑定
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 更新流程
|
||||||
|
|
||||||
|
### 3.1 修改 Rust 接口
|
||||||
|
|
||||||
|
1. 在 `zx_document_core/src/` 中修改或新增函数/类型
|
||||||
|
2. 在 `zx_document_ffi/src/lib.rs` 中导出新接口
|
||||||
|
3. 如需新增 UDL 定义,更新 `zx_document.udl`
|
||||||
|
|
||||||
|
### 3.2 重新生成 Swift 绑定
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd zhixi-document-runtime
|
||||||
|
cargo build --release -p zx_document_ffi
|
||||||
|
|
||||||
|
# 生成 Swift 绑定
|
||||||
|
uniffi-bindgen generate \
|
||||||
|
crates/zx_document_ffi/src/zx_document.udl \
|
||||||
|
--language swift \
|
||||||
|
--out-dir ../ios-projects/AIStudyApp/AIStudyApp/Core/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 构建 xcframework
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# iOS arm64
|
||||||
|
cargo build --release -p zx_document_ffi --target aarch64-apple-ios
|
||||||
|
|
||||||
|
# iOS Simulator arm64 (Apple Silicon Mac)
|
||||||
|
cargo build --release -p zx_document_ffi --target aarch64-apple-ios-sim
|
||||||
|
|
||||||
|
# iOS Simulator x86_64 (Intel Mac)
|
||||||
|
cargo build --release -p zx_document_ffi --target x86_64-apple-ios
|
||||||
|
|
||||||
|
# 打包 xcframework
|
||||||
|
xcodebuild -create-xcframework \
|
||||||
|
-library target/aarch64-apple-ios/release/libzx_document_ffi.a \
|
||||||
|
-library target/aarch64-apple-ios-sim/release/libzx_document_ffi.a \
|
||||||
|
-output ZxDocumentRuntime.xcframework
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.4 更新 Xcode 项目
|
||||||
|
|
||||||
|
1. 替换 `AIStudyApp/Core/ZxDocumentRuntime.xcframework`
|
||||||
|
2. 替换 `AIStudyApp/Core/zx_document.swift`
|
||||||
|
3. 在 Xcode 中 Clean Build Folder(Cmd+Shift+K)
|
||||||
|
4. 重新编译
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 新增接口 checklist
|
||||||
|
|
||||||
|
- [ ] Rust 类型实现 `Serialize + Deserialize + uniffi::Record/Enum`
|
||||||
|
- [ ] FFI 层 `pub extern "C"` 导出函数
|
||||||
|
- [ ] UDL 文件声明接口
|
||||||
|
- [ ] Swift 绑定重新生成
|
||||||
|
- [ ] xcframework 重新编译(至少 arm64 + sim)
|
||||||
|
- [ ] iOS 编译通过
|
||||||
|
- [ ] 单元测试通过(`cargo test -p zx_document_core`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 常见问题
|
||||||
|
|
||||||
|
### 5.1 xcframework 架构缺失
|
||||||
|
|
||||||
|
**症状**:`While building for macOS, no library for this platform was found`
|
||||||
|
|
||||||
|
**原因**:xcframework 仅包含 iOS 架构,Mac Catalyst 构建试图链入
|
||||||
|
|
||||||
|
**处理**:确保 Scheme 仅勾选 iOS target,或为 Mac Catalyst 添加 `aarch64-apple-ios-macabi` 目标
|
||||||
|
|
||||||
|
### 5.2 uniffi 版本不匹配
|
||||||
|
|
||||||
|
**症状**:`uniffi::ffi::foreigncallbacks` not found
|
||||||
|
|
||||||
|
**处理**:确保 `Cargo.toml` 中 uniffi 版本与 `uniffi-bindgen` CLI 版本一致
|
||||||
|
|
||||||
|
### 5.3 Swift 类型不匹配
|
||||||
|
|
||||||
|
**症状**:`Cannot convert value of type 'X' to expected argument type 'Y'`
|
||||||
|
|
||||||
|
**处理**:重新生成 `zx_document.swift`(uniffi-bindgen 输出),确保与 xcframework 版本对应
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 版本管理
|
||||||
|
|
||||||
|
| Rust crate | 当前版本 | FFI 接口数 |
|
||||||
|
|------------|:--:|:--:|
|
||||||
|
| zx_document_core | 0.1.0 | — |
|
||||||
|
| zx_document_ffi | 0.1.0 | 12 |
|
||||||
|
| uniffi | 0.28 | — |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 相关文档
|
||||||
|
|
||||||
|
- [V2 事件 Pipeline 架构](./v2-event-pipeline.md)
|
||||||
|
- [阅读信息采集接入文档](./reading-info-integration.md)
|
||||||
Loading…
x
Reference in New Issue
Block a user