開發外賣訂餐軟體時,「動態倒計時」與「騎手 GPS 定位」是核心技術難點。本文針對不同技術棧 (Web/App/Hybrid) 提供成熟方案選型建議。
| 平台 | 推薦方案 | 核心 API | 優/缺點 |
|---|---|---|---|
| Web (PC/移動端) | 前端輪詢 + WebSocket | setInterval / WebSocket / Server-Sent Events | ✅ 即時性強 ❌ 需後端支援長連線 |
| 原生 Android | CountDownTimer / Handler | CountDownTimer(ms, interval) | ✅ 系統級精準 ❌ 需處理 Activity 生命週期 |
| 原生 iOS | Timer / DispatchSourceTimer | Timer.scheduledTimer() | ✅ RunLoop 整合良好 ❌ 後台執行受限 |
| Flutter/React Native | JS 計時器 + 原生橋接 | setInterval / NativeModules | ✅ 跨平台統一 ❌ JS 執行緒阻塞影響精度 |
// 前端
const ws = new WebSocket('wss://api.example.com/order/track/{{orderId}}');
ws.onmessage = (e) => {
const data = JSON.parse(e.data);
if (data.type === 'COUNTDOWN') updateCountdownUI(data.seconds);
if (data.type === 'LOCATION') updateCourierMarker(data.lat, data.lng);
};
// 後端 (Spring Boot 範例)
@MessageMapping("/order/track/{orderId}")
@SendToUser("/queue/updates")
public OrderUpdate trackOrder(@DestinationVariable String orderId) {
return orderService.getRealTimeStatus(orderId); // 含倒計時秒數、騎手座標
}
// 僅 HTTPS 或 localhost 可用
navigator.geolocation.watchPosition(
(pos) => sendToServer(pos.coords.latitude, pos.coords.longitude),
(err) => handleError(err), // 權限拒絕、超時、不可用
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
);
⚠️ 限制:需使用者授權、室內定位誤差大、iOS Safari 後台不可用。
| 平台 | 核心框架 | 關鍵類 | 後台定位 |
|---|---|---|---|
| Android | Google Play Services Location | FusedLocationProviderClient | ✅ 前台服務 + 權限 |
| iOS | CoreLocation | CLLocationManager | ✅ Background Modes + 始終授權 |
startForeground() + 通知欄顯示「正在配送」,防止系統殺進程。GEOADD、GEORADIUS)。WAITING → ACCEPTED → PICKED_UP → DELIVERING → COMPLETED,每狀態觸發對應倒計時邏輯。技術選型核心原則:倒計時用前端計時器同步服務端基準時間,GPS 定位必須在原生端實現並透過長連線推送至前端,避免輪詢造成的延遲與伺服器壓力。