地圖鑑 App:技術清單與開發過程
地圖鑑是一款在地圖上認行政區的 iOS 遊戲,前身是「ChiZu 嶼」。這篇整理它用到的技術和開發過程。
基本資料
- 平台:iPhone / iPad,iOS 17 以上
- 規模:Swift 42 個檔案、約 1.2 萬行;測試 19 個檔案
- 內容:40 張卡、289 關,從台灣、日本一路擴充到五大洲
- 語言:繁中、簡中、英文、日文、韓文
App 端
- SwiftUI:所有畫面。狀態管理用
Observation(@Observable),沒有另外引入架構框架 - MapKit:實景盤面用
MKMapView的衛星影像,透過UIViewRepresentable包進 SwiftUI - Core Graphics:行政區自己畫在地圖上,不用 MapKit 內建的 overlay renderer(原因見下方「踩過的坑」)
- Canvas:平滑盤面(不用網路的向量地圖)直接用 SwiftUI
Canvas畫 polygon - AVFoundation:8-bit 風格音效
- String Catalog(
.xcstrings):介面多語系,key 直接用繁中原文 - Firebase Analytics:唯一的第三方套件,用 Swift Package Manager 安裝,用來看各關卡的遊玩與流失
- PrivacyInfo.xcprivacy:隱私權清單,App Store 要求
資料端
地圖與題庫都打包在 App 內(約 43 MB 的 JSON),不用連網下載。資料由另一個 Laravel 專案產生:
- Laravel + MySQL:存行政區邊界、層級、譯名,用 artisan 指令跑整條 pipeline
- Python(shapely):合併幾何,例如把日本政令市底下的區併回一個市
- OpenCC:日文新字體轉繁中、繁中轉簡中
- Wikidata:補台灣、日本行政區的多語名稱
- 保留拓樸的簡化:相鄰行政區的共用邊界只簡化一次,兩邊拿到同一條線,畫出來不會有縫或雙線
圖資來源:
- 台灣:taiwan-atlas(TopoJSON)
- 日本:GitHub 上的 TopoJSON
- 多數國家:Natural Earth 10m
- 法國:IGN;義大利:ISTAT
- 印尼:印尼統計局(BPS)的縣界拼成 38 省
開發過程
| 版本 | 日期 | 重點 |
|---|---|---|
| 初版 | 2026-02 | 只有日本 47 都道府縣,兩階段點選:先選大區域,再選縣 |
| 1.3 | 2026-03 | 加台灣;題庫與地圖資料分開;接 Firebase |
| 2.0 | 2026-09 | 8-bit 風格改版;新增「填圖闖關」玩法 |
| 2.1 | 2026-09 | 加韓國、美國;地名多語系 |
| 2.2 | 2026-09 | 介面五種語言;iPad 截圖腳本 |
| 2.3 | 2026-11 | 加泰國、歐洲、法德義西、馬來西亞、菲律賓 |
| 2.4 | 2026-11 | 一次加 28 張卡:亞洲、中東、非洲、中南美、大洋洲與更多歐洲國家 |
踩過的坑
- 相鄰行政區之間有細縫:MapKit 一個 polygon 一個 renderer,各自做反鋸齒,邊界會透出底圖。改成一次 pass 畫完所有 polygon
- 畫面太慢:MapKit 每個 tile 都會叫一次 draw,美國全國視角一個 tile 要 3.5 秒。座標換算只做一次,每個縮放級距快取一份 CGPath,只畫碰到這個 tile 的 polygon,結果降到 0.2 ms
- 點擊判定不一致:有三個畫面各自寫了一份點擊判定(ray casting),只有一份有處理挖洞的 polygon,實景盤面因此把台北市的點擊算成新北市。最後統一成一份
GeoGeometry - 有爭議的領土:國界照聯合國認定,例如西撒哈拉單獨一格、戈蘭高地歸敘利亞
工具
- Xcode、XCTest
- Claude Code:寫程式、code review、App Store 截圖與送審資料
- 自寫腳本:App Store 截圖(
simctl固定狀態列 9:41)、上架文字檢查