# Theory of Happiness- an iOS App for traveling in Japan
### by a crazy addict for Japanese castles and ramen

## GitHub public repo:
https://github.com/AliaGo/Theory-of-Happiness.git
## 創作動機 Motivation:
身為狂熱拉麵迷跟城堡迷,過去一年吃了80碗拉麵以及收集了45座日本百名城,拜訪城堡的旅程中總是想吃拉麵,就想到:有沒有一款app可以查詢城堡周遭的拉麵資訊呢?但翻遍了台灣和日本的apple store,都只有拉麵或城堡各自的app,於是我又想:那何不自己創作一款專屬app?!
我的Swift學習之路便從此開始。
## 簡介 Introduction:
這是一款以「**旅行 × 收集 × 分享**」為核心概念所開發的 iOS App,使用者可以透過 GPS 驗證造訪地點(如日本百名城、人氣拉麵店等),取得專屬的數位印章,並在 App 上記錄與分享自己的旅遊足跡,並看到其他使用者的即時分享。
同時,針對台灣地區使用者,提供各種繁體中文版本的城堡、拉麵相關的知識及介紹,來源皆為可信度高的日本網站。
本專案採用 Swift + Firebase 技術實作,並結合社群互動與實用資訊查詢,期望打造一個結合成就感與探索樂趣的數位旅遊體驗平台。
本筆記將記錄開發過程中的架構設計、技術實作、問題排除與未來優化方向。
> The core concept of my app is "**Travel × Collect × Share.**"
Users can verify their visits to specific locations (such as Japan’s Top 100 Castles or popular ramen shops) via GPS and collect unique digital stamps as proof of their journey. They can also record and share their travel experiences within the app and view real-time posts from other users.
For users in Taiwan, the app provides Mandarin Chinese content introducing various castles and ramen-related knowledge, sourced from highly credible Japanese websites.
The project is built using Swift and Firebase, combining social features with informative content to create a rewarding and engaging digital travel experience.
This note documents the development process, including architectural design, technical implementation, problem-solving, and future improvement plans.
## 主要功能 Core Features:
### 1. 收集印章 Collecting stamps
1. 使用者上傳圖片 user upload photo
* utilize PhotosPicker to pick photo.
* transfer image to Data, then temporarily uploading to Firebase Storage.
* get the URL of image, then store into "posts" collection in Firestore (field:imageURL).
2. GPS 座標偵測 Get the GPS data
* read EXIF GPS metadata.
* if no GPS metadata, then use CLLocationManager to get the current position of user.
3. 比對城堡資料 Compare to the data of castles
* search the latitude and longtitude data of "castles" collection in Firestore.
* utilize Haversine formula to calculate the distance from castles to the location of photo , and filter the castle from where the distance is not further than 1km.
* 若找到符合條件的城堡,視為有效造訪。
4. 核發數位印章
* add or update the subcollection of "collectedStamps" to the fields of "users" collection in Firestore.
* async update the fields of posts and show the "stamp collected" message to user by alert view.
### 2. 貼文牆 Posts
1. 新增貼文 Create posts
* user creates post and manually add the tags of castle or ramen shop, and then store in Firestore.
* user will get the castle stamp or ramen points based on the info of the photo of post.
2. 標籤管理 Tags
* the tags added by user can be implemented in frequency analysis and popular tag tracking.
3. 貼文牆呈現 Post Wall Display
* fetches all posts from Firestore and supports real-time updates
4. 延伸功能規劃 Future improvements
* user can like, comment, or bookmark posts
* Tap a tag to explore related content.
* Search posts by GPS, tags, or keywords (e.g., castle names, seasons, ramen shop names).
### 3. 百名城&拉麵百名店資訊查詢 100 Castles & Ramen Info
* Basic info: name, region, short descriptions, photos, and etc.
* Map-based UI for geographic browsing and route planning
* Search & filter by keyword, region, or type
* Save **Favorite** castles and ramen shops to a personal list
| Castle stamps example | Screenshot from Homepage |
| -------- | -------- |
|  | 
## 核心技術實作 Key Implementation:
### 1. Firebase 雲端架構整合
* 使用 Firebase Firestore 儲存各種資料庫,包含user、castle、ramen、post、card、tag、product 等。
* 透過 Firebase Storage 儲存上傳圖片並取得 URL,再寫入 Firestore。
* 所有時間戳統一使用 FieldValue.serverTimestamp() 以確保一致性。
* 貼文中的標籤會同步更新至 tags collection,維護標籤名稱與使用次數(count)以利日後排序與推薦邏輯。
### 2. SwiftUI + MVVM 架構實作
* 採用 SwiftUI 作為 UI 框架,並實踐 MVVM 架構,將 UI 呈現、邏輯處理與資料存取清晰分離。
* 使用 @StateObject、@ObservedObject、@Binding 管理元件間資料流與狀態同步。
* 結合 Task 與 @MainActor 確保 Firestore 操作於主執行緒安全執行,防止 UI 當機。
### 3. 使用者身份驗證(Authentication)
* 整合 Firebase Authentication,提供兩種登入方式:
* Email + 密碼註冊/登入
* Google Sign-In
* 登入後可取得使用者 UID,做為與貼文、印章、收藏紀錄的關聯依據。
* 實作登入狀態監控,確保未登入用戶無法進入發文或收藏功能。
### 4. 標籤系統與使用者輸入體驗
* 實作標籤輸入、即時搜尋與篩選機制,僅允許最多三個標籤。
* 標籤可來自資料庫現有記錄或使用者自創,並即時與貼文同步。
* 上傳貼文時,自動將標籤使用次數更新至 Firestore,用以追蹤熱門標籤並支援後續推薦系統。
### 5. 資料來源與自建資料庫
* 使用 Python + BeautifulSoup 撰寫爬蟲腳本,自動爬取並解析以下網站之資料,建立完整的日本百名城與拉麵名店資料集:
* Tabelog ラーメン百名店(https://award.tabelog.com/ramen)
* 日本100名城官方網站(https://www.100finecastles.com/castles-list/)
* ホームメイト 城研究所(https://www.homemate-research-castle.com/)
* 爬取內容包含城堡名稱、地區分類、照片連結、建造歷史簡介、拉麵店名、地址與得獎年份等,做為 App 初期導入的基礎資料集。
### 6. 使用者照片與 GPS 打卡機制
* 使用 PhotosPicker 實現圖片選擇與預覽功能。
* 上傳照片時,擷取照片中的 GPS EXIF 資訊,進行定位比對(如與城堡/拉麵地點的座標匹配)來判斷是否符合打卡資格。
* 若成功比對,即給予該地點專屬數位印章,並新增至使用者印章收藏中。
## UI/UX Design:
1. 首頁 HomePage
| 首頁1 | 首頁2 | 所有城堡資訊 | 所有拉麵資訊 |
| -------- | -------- | -------- | -------- |
|  |  |  |  |
| 城堡詳細頁面 | 拉麵詳細頁面 | 拉麵篩選(filter) |
| -------- | -------- | -------- |
|  |  |  |
2. 最愛清單 Saved
| 最愛城堡 | 城堡加入最愛(長按) | 最愛拉麵 | 拉麵加入最愛(右上角愛心) |
| -------- | -------- | -------- | -------- |
|  |  |  |  |
3. 貼文牆 Add Post
| 貼文頁面 | 貼文內容 | 新增貼文、自訂Tag |
| -------- | -------- | -------- |
| |  |  |
4. 探索地圖 Explore
| 空地圖 | 城堡地圖(按下底部城堡按鈕) | 城堡資訊(Sheet) |
| -------- | -------- | -------- |
|  |  | |
5. 個人頁面 Profile
| 個人資訊 | 更改設定 | 印章收藏冊 | 使用指南 | 點數商店 |
| -------- | -------- | -------- | -------- | -------- |
|  | |  |  | |
## 未來優化方向 Future Improvement:
* 目前有些資料仍是日文,需統一成中文
* 新增多語系對應(日文、英文版本)
* 資料更完善:新增近五年拉麵百名店店家資訊
* 地圖功能:新增使用者已去過地點清單並顯示在地圖上,新増拉麵地圖必導入路線規劃功能
* 新增每日任務,如四選一知識題目、小遊戲等
* 貼文牆增設篩選功能,可以從熱門標籤、貼文種類、地點做篩選
* 新增Ad欄位增加app收入