◀ 上一層:App 設計 | 下一章:BLE 設備整合 ▶


📱 技術堆疊 (Tech Stack)

核心技術

平台: iOS

技術選型

類別 技術 用途
框架 React Native 0.73+ 跨平台 App 開發
語言 TypeScript 型別安全的開發
BLE react-native-ble-plx 藍牙裝置整合
狀態管理 Redux Toolkit / Zustand 全域狀態管理
網路 Axios HTTP 請求
本機儲存 WatermelonDB 本地資料庫 (見 03.4)
影片播放 react-native-video 課程影片播放
導航 React Navigation 畫面路由

🏗️ App 分層架構

┌─────────────────────────────────────────┐
│              App Architecture           │
│                                         │
│  ┌────────────────────────────────────┐│
│  │         UI Layer                   ││
│  │  (Screens / Components)            ││
│  │                                     ││
│  │  - LoginScreen                      ││
│  │  - DeviceConnectionScreen           ││
│  │  - WorkoutScreen                    ││
│  │  - WorkoutSummaryScreen             ││
│  │  - HistoryScreen                    ││
│  │  - SettingsScreen                   ││
│  └────────────────────────────────────┘│
│              ▲│                          │
│              ││ (State / Props)          │
│              ▼│                          │
│  ┌────────────────────────────────────┐│
│  │      Service Layer                 ││
│  │                                     ││
│  │  - WorkoutEngine                    ││
│  │  - BLEManager                       ││
│  │  - APIClient                        ││
│  │  - AuthService                      ││
│  │  - StorageService                   ││
│  └────────────────────────────────────┘│
│              │                           │
│              ▼                           │
│  ┌────────────────────────────────────┐│
│  │      Data Layer                    ││
│  │                                     ││
│  │  - WatermelonDB (local)            ││
│  │  - Axios (network)                 ││
│  │  - react-native-ble-plx (BLE)      ││
│  └────────────────────────────────────┘│
└─────────────────────────────────────────┘

使用 React Navigation (Tab-based):

Root Navigator
├─ Auth Stack (未登入)
│  └─ LoginScreen
│
└─ Main Tab Navigator (已登入)
   ├─ Home Stack (訓練選擇)
   │  ├─ TrainingListScreen
   │  └─ TrainingDetailScreen
   │
   ├─ Workout Stack (運動中)
   │  ├─ DeviceConnectionScreen
   │  ├─ WorkoutScreen
   │  └─ WorkoutSummaryScreen
   │
   ├─ History Stack (歷史記錄)
   │  ├─ HistoryListScreen
   │  └─ HistoryDetailScreen
   │
   └─ Settings Stack (設定)
      └─ SettingsScreen

🎨 狀態管理

方案選擇

建議使用: Redux Toolkit 或 Zustand

狀態分類

類型 存放位置 範例
全域狀態 Redux Store / Zustand 使用者登入狀態、BLE 連線狀態、當前運動 session
本地狀態 React useState / useReducer 表單輸入、UI 開關
伺服器狀態 RTK Query / React Query API 資料快取
持久化狀態 WatermelonDB 運動記錄、課程清單

設計原則

  • 單一來源真相 (Single Source of Truth): 每個狀態只有一個來源
  • 不可變性 (Immutability): 使用 Redux Toolkit 的 immer 確保狀態不可變
  • 可預測性 (Predictability): 透過 Actions 和 Reducers 控制狀態變化

🔧 核心服務模組

1. WorkoutEngine (services/WorkoutEngine.ts)

職責: 管理運動 session 生命週期

功能:

  • 開始 / 暫停 / 恢復 / 結束運動
  • 接收 BLE metrics 事件並記錄
  • 計算即時統計 (平均功率、總距離等)
  • 完成 session 後生成摘要
  • 觸發上傳至後端 (透過 APIClient)

實作方式: TypeScript Class 或 Custom Hook

狀態管理: Redux store 或 Zustand

資料儲存: 運動中寫入 WatermelonDB


2. BLEManager (services/BLEManager.ts)

職責: 藍牙設備連線與通訊

使用套件: react-native-ble-plx

功能:

  • 掃描 SolidFocus 設備 (SF_PRIMARY_SERVICE_UUID)
  • 連線、服務發現、特徵訂閱
  • 解析 FTMS Indoor Bike Data / Rower Data
  • 發送控制指令 (Start/Stop/Pause/阻力調整)
  • 監聽 Device Status 通知

事件處理: EventEmitter 或 Redux Actions

權限管理:

  • iOS: Info.plist 設定 NSBluetoothAlwaysUsageDescription
  • Android: PermissionsAndroid.request(BLUETOOTH_SCAN, BLUETOOTH_CONNECT)

詳細設計: 見 03.2 BLE 設備整合


3. APIClient (services/APIClient.ts)

職責: 與後端 API 通訊

使用套件: Axios

功能:

  • 使用者登入 / SSO 認證
  • 上傳運動紀錄 (Batch Upload)
  • 下載課程清單與影片 metadata
  • Token refresh (Interceptor 自動處理)

攔截器 (Interceptors):

  • Request: 自動附加 JWT Token (Authorization: Bearer <token>)
  • Response: 401 時自動 refresh token

錯誤處理: 統一錯誤處理與 Toast 提示

API 規格: 見 第 4 章:API Contract


4. StorageService (services/StorageService.ts)

職責: 本機資料持久化

使用套件: WatermelonDB

功能:

  • 儲存運動中的 metrics (防止網路中斷遺失)
  • 快取課程資訊 (Trainings, Videos)
  • 儲存 Pending Sessions (待上傳)
  • 離線 session 暫存,待網路恢復後上傳

Schema 設計: 見 03.4 本地資料庫 Schema


🚀 App 啟動流程

App.tsx (Entry Point)
    ↓
Redux Store / Zustand Store 初始化
    ↓
Check Login State (從 Local DB 讀取)
    ↓
    ├── Not Logged In → NavigationContainer → LoginScreen
    │                                            ↓
    │                                      Login Success
    │                                            ↓
    │                                      資料同步 (Sync)
    │                                            ↓
    └────────────────────────────────────→ Main Tab Navigator
                                                 ↓
                                           Check BLE Permissions
                                                 ↓
                                           BLEManager.initialize()
                                                 ↓
                                           Auto-connect to last device
                                                 ↓
                                           Ready for Workout

重要設計原則

  • 看到主畫面時,一定已經 Login + 資料同步 + BLE 連線完成
  • Login 後必須先完成資料同步,才能進入主畫面
  • 詳細流程見 03.3 資料流與同步策略

🔗 相關章節


◀ 上一層:App 設計 | 下一章:BLE 設備整合 ▶