Slide 1

Slide 1 text

山手線を徒歩で一周してわかった、 位置情報アプリは「足」が最強のデバッガー ひなっこ @hinakkograshi 2026/09/13 iOSDC Japan 2026

Slide 2

Slide 2 text

山手線一周ウォーキング Yamanote Walk

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

個人開発アプリv1.0 概要 iOS 17+ / SwiftUI + SwiftData • 駅チェックイン GPS の距離計算で自動発火 +手動ボタン • 位置追跡・地図 3D起伏(.realistic)/進行方向に地図を回転 • 経路案内 MKDirectionsを位置更新のたびに再計算 • 歩行データ HealthKit(距離・歩数・カロリー)

Slide 5

Slide 5 text

山手線一周ウォーキング 完 🏃

Slide 6

Slide 6 text

フィールドワークによって 発覚した課題の数々

Slide 7

Slide 7 text

v1.0課題①: 駅の区間ごとの歩数が更新されない • 5分以上歩いても画面は「0.0km/0歩」のまま • 駅の区間の歩数がリアルタイムに取得できない

Slide 8

Slide 8 text

v1.1改善: CMPedometerを使用する 原因 HealthKitのHKStatisticsQueryでは リアルタイムの歩数が反映できない HealthKitからCMPedometerに変更 queryPedometerData(from:to:)で駅区間の距離・歩数を取得

Slide 9

Slide 9 text

v1.0課題②: バッテリーが持たない • iPhoneのバッテリー消耗が激しい • モバイルバッテリーで2機使用した • 端末発熱が著しい 原因 • 3D地図の常時GPU描画 GPS最高精度の常時稼働 →バックグラウンドのアプリの設計そのものを見直す必要があった

Slide 10

Slide 10 text

v1.1改善: GPS・測位の構造を変更 ① CLLocationManager の精度を見直す ② 静止時に測位を止める v1.0 v1.0 desiredAccuracy = activityType は未設定(.other 扱い) kCLLocationAccuracyBest pausesLocationUpdatesAutomatically = false v1.1 v1.1 desiredAccuracy = fi kCLLocationAccuracyNearestTenMeters activityType = . tness pausesLocationUpdatesAutomatically = true

Slide 11

Slide 11 text

v1.1改善: バックグラウンド前提のアプリ設計に見直す v1.0 バックグラウンドでも止めない manager.allowsBackgroundLocationUpdates = true manager.pausesLocationUpdatesAutomatically = false manager.startUpdatingLocation() v1.1 ライフサイクルで切替 func handleEnterBackground() { manager.stopUpdatingLocation() manager.startMonitoringSignificantLocationChanges() } func handleBecomeActive() { manager.stopMonitoringSignificantLocationChanges() manager.startUpdatingLocation() manager.monitoredRegions.forEach { manager.requestState(for: $0) } }

Slide 12

Slide 12 text

v1.1改善: 再描画と再計算の範囲を絞る ④ 3D地図 → 2D地図・回転追従OFF v1.0 .mapStyle(.standard(elevation: .realistic)) cameraPosition = .userLocation( followsHeading: true, fallback: .automatic ) v1.1 .mapStyle(.standard(elevation: .flat)) cameraPosition = .userLocation( followsHeading: false, fallback: .automatic )

Slide 13

Slide 13 text

いつかデバッグしない となあ〜 😟

Slide 14

Slide 14 text

iOSDC採択通知🎉

Slide 15

Slide 15 text

山手線一周ウォーキング 完 2回目

Slide 16

Slide 16 text

パフォーマンス比較の条件と方法 v1.0.0: iPhone14Pro (iOS26.6) バッテリー最大容量 88% v1.1.0: iPhone14Pro (iOS26.6) バッテリー最大容量 88% 同一ルート・同条件で計測 • 低電力モードをオフ • 明るさの自動調節をオフ • 輝度を50% • 自動ロック 30秒

Slide 17

Slide 17 text

HealthKitとCMPedometerの計測方法 検証条件 • タイマーでCMPedometerと 計測値 API / メソッド 取得する値 CMPedometer CMPedometerData .queryPedometerData .numberOfSteps 比較での使用用途 HealthKit同時にクエリ実行 • 山手線一周サンプルを収録 • 30駅ごとに区間(駅間)単位で も比較 HKStatisticsQuery HKStatistics .sumQuantity() CMPedometerの歩数 HealthKitの歩数

Slide 18

Slide 18 text

HealthKitとCMPedometerの比較結果 区間ごとの歩数・距離(東京駅を起点に3区間) 区間 有楽町→新橋 (約0.9km) 有楽町→新橋 (約1.2km) 新橋→浜松町 (約1.3km) CMPedometer 歩数 HealthKit 歩数 CMPedometer 距離 HealthKit 距離 1,263歩 0歩 0.881km 0.000km 1,747歩 1,045歩 1.168km 0.684km 2,096歩 1,033歩 1.386km 0.685km 駅間のような短い区間ではHealthKitは即時反映ができない

Slide 19

Slide 19 text

解決①: 駅の区間ごとの歩数が動かない 採用 CMPedometer • 歩数と距離の反映が速い HealthKit • 取得可能なデータが幅広い (心拍数・血圧・睡眠) • Capability追加が不要 • 取得までに時間がかかる 歩数と距離の即時反映の面でCMPedometerを採用

Slide 20

Slide 20 text

計測方法 バッテリー消耗量とCPU使用量の比較 指標 バッテリー残量 API / メソッド 算出方法 比較での使用用途 UIDevice.current 開始(%) - 終了(%) 消費速度算出(%/h・%/km) .batteryLevel /経過時間 の主指標 CPU使用時間 task̲info(TASK̲BASIC̲INFO) (累積) → user̲time + system̲time セッション完了時の バージョン間の総CPU負荷を比 累積のCPU時間 較

Slide 21

Slide 21 text

改善結果 バッテリー消費速度(%/時間) 60%削減 CPU使用時間(累積・秒) 92%削減

Slide 22

Slide 22 text

せ〜の、ヨシ👉 🎉

Slide 23

Slide 23 text

1回目 2回目

Slide 24

Slide 24 text

伊能忠敬界隈

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

ご清聴ありがとうございました!