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