忙了三個月,終於有時間來打一份完整的報告了,感謝這陣子以來幫助過我們的夥伴!因為有你們的幫忙,又再次讓 GPS 的流量與用戶達到巔峰!

團隊到現在已經三年(2016年開始)了,每一年都有要面對的難題與課題需要解決,今年我們面對了 Google Maps 的漲價,但是我們採取上架 App 的方式讓這個難關順利的度過。
或許很多人會納悶,你們的 App 沒有廣告,而且也沒有對外募款,看起來也沒有賺錢的地方,那為什麼你們要這樣忙死自己呢?
沒錯,我們很忙!但是我們秉持用戶「最好操作」的原則,所以 App 沒有任何廣告的出現,同時因為不想有太多的金錢糾紛,所以我們暫且沒對外公開募款,這就是我們的「初衷」。
開銷呢?
加上攜帶 GPS 的團員們目前約有 20 幾位夥伴,所以活動期間的 GPS 開銷都是由我們平均分擔的;一直以來有很多朋友都會私訊我,希望能夠贊助我們在費用上的開銷,但是目前的開銷我們還可以自行吸收,所以感謝各方信眾主動的提問,等到有一天我們負荷不了自然會跟大家報告的,所以請大家放心!
其實身為熱愛鄉土的「App 開發者」,當然能希望活動中有更多人使用我們的 App,所以當越多人使用、下載時,其實就是對我們最大的鼓勵!這也就是為什麼我們沒有錢賺,卻依然熱血的忙碌完成這項任務的原因!
成果分享
今年算是第 4 年的服務了,對於前幾年的數據有興趣的夥伴可以參考 這篇 裡面有詳細的報告往年的成績喔!而今年我們主要強調的是 App,所以!以下會針對今年的重點分享喔!

團隊是在今年農曆年前後才開始設計今年的 App 的,大家都會覺得每一年不是都是一樣的 GPS 嗎?那就把去年的程式碼拿出來用就好呀!
當然也可以這樣做,但因為團隊為了讓活動完美無缺點,所以大家就把去年各自學到的新技術發揮在 GPS 上,讓每一年都可以讓信眾有更好的體驗!所以每一年的系統,都是全新的!從後端系統、後台管理、網站前台、App iOS 學習、 Android 的與夥伴規劃,都是每一年重新開始的,當然今年 App 是第一年!
2019 年,也就是今年,我們有約 29 萬個安裝數,這個數字其實令我震驚,加上官方的 GPS 與其他的民間夥伴的 GPS,整體關注白沙屯媽祖的用戶數應該超過 35萬以上!

在 App Store 上我們也拿下了將近一週的「免費排行榜第 1 名」,這對於我們第一次上架 App 來說是一種最大的鼓勵與回饋,看到各位下載的用戶留言鼓勵,也讓我們滿滿的感動!
而且在 Store 上評分數也超過 3千則,並且有維持在 5 顆星星喔!真的非常的感謝各位對我們的支持!

連在 Android 平台上的 Play 商店也拿下第一名了,相較於 iOS 平台的免費排行榜,其實要在 Google Play 商店拿第一名,其實真的是要有大量的用戶才有機會!可見白沙屯媽祖的魅力無法擋!

這次活動花費約「1萬1千元」左右,基本上就是 伺服器+地圖+上架費用。其實整體算是便宜了,比去年的資訊開銷少了快 9千元左右,比原本預估的少了快一半!主要還是要感謝各位夥伴使用 App 替我們省下大量的地圖開銷喔!

由於採用 App 設計,所以這次大家應該也都有注意到,我們會主動發送推播給所有用戶,提醒今天媽祖在哪裡駐駕,明天幾點起駕的功能。
明年一樣我們會將這個功能好好發揮,讓大家可以無憂慮的追隨媽祖喔!

開發心得
這個專案每年的資訊工程幾乎都是由我完成的,以下就是這次我個人完成的項目:
- 後端程式碼 - PHP
- AWS 系統架設
- EC2 - 後端伺服器
- RDS - 資料庫
- S3 - 雲端空間
- CloudFront - CDN
- Certificate Manager - 憑證管理
- GPS 訊號後台收集與校正
- 前端網頁地圖功能
都是一個人完成,而這次也加入了開發 iOS App,其實成就感頗高!所以這篇會著重在 iOS Swift 的學習心得,若要看其他部分也可以參考2016 的心得!
廢話不多說。寫 App,當然是直接先給鏈結下載呀,有興趣的夥伴歡迎下載囉!
- App - 白沙屯 GPS
- 網站 - 2019 白沙屯 GPS
- 粉專 - 白沙屯媽祖在哪裡?
回想起當初想學 App 已經是三年前了,當初還是寫 Object-C,但因為本身工作是專職的網站前後端工程師,所以一直沒有時間好好的專研,頂多就是想到就寫個小 App,了解一下推播、Watch App.. 等,但都一直沒上架過,所以就默默的繳了三年的開發者費用,這就是信仰!?(疑)
在今年,我終於上架了我第一個 App
以往這個活動我都是使用網頁技術來呈現,但是從去年開始 Google Maps 就調漲了費用、收費方式,於是不得不另尋他路改採用 App 的方式來省錢,Google Maps 官方也寫了,採用 App SDK 好像基本的地圖就可以無上限使用,所以在今年一月底,我正式開始籌備今年度的 GPS 系統!
這個系統我想對很多資深的工程師來說困難度應該不高,主要就是讀取 API 並且將內容呈現,所以對我來說幾項重點:
- UI - Constraint
- API - Alamofire
- Maps - Google Maps
- 送審 - Reject
UI - Constraint
以 UI 來說,我有練習過 Obj-c 的經驗,應該不難,就只是語法上的差異,而我在刻板時,其實很不習慣使用 storyboard,所以我的專案內都是採用 NSLayoutConstraint 的方式將版型兜出來,可能是 css 切版習慣了,所以還是偏愛 Constraint 的方式來調整版型,所以自己寫了個簡單的 Lib 來使用,例如以下的方式讓我自己方便調整版型!
OA.layout(self.view, nameView) {
$0.at(.left, .equal, .left, 8)
$0.at(.right, .equal, .right, 8)
$0.at(.top, .equal, self.view.safeAreaLayoutGuide, .top, 8)
$0.at(.height, .equal, 18)
}其中包含 TableView 的 Cell 我也是這樣做,之後我還打算加入可以判斷螢幕寬高、旋轉的條件!
至於圖示,因為本身對於設計真的很外行,所以沒辦法產出我想要的 icon,但因為有網頁前端的經驗,所以很常使用 SVG 的 icon,於是使用了 SwiftSVG 這個套件,所以 App 中的圖示,都是採用 SVG 的方式呈現。
API - Alamofire
API 的方式我採用 Alamofire 這個套件,因為以前 Obj-c 是使用 AFNetworking,上去 GitHub 看了一下,感覺他們推薦使用 Alamofire,所以這專案我採用 Alamofire,使用方式網路上很多資源,而我把它進階包了一下,因為 closure 擺在後面可以直接這樣用,所以語意上好像更清楚了(?),範例如下:
class Api {
static var get = ApiGet()
static var post = ApiPost()
}
class ApiGet {
public func path(_ closure:@escaping (([String: Any]) -> Void)) {
Alamofire.request("API", method: .get).validate().responseJSON { response in
switch response.result {
case .success(let json):
return closure(json as! [String : Any]);
case .failure(let error):
// Error Func
}
}
}
}
class ApiPost {
public func path(_ closure:@escaping (([String: Any]) -> Void)) {
// 以下省略
}
}
Api.get.path { json in
// 取得資料後要做的事
}
Api.post.location { json in
// 完成 Post 後要做的事
}不過我其實也想說要不要改用原生的 NSURLConnection 之類的,打造出自己的 Call Api 工具,這等之後熟一點後,再重新送一版好了XD
Maps - Google Maps
關於地圖,其實我原本想採用原生的 MapKit,但想到活動時,可能會有很多人不習慣 Apple Maps 的樣式,於是才依然使用 Google Maps。
安裝套件方法其實 官方文件 照著走就可以完成了,所以沒太大的難點,而使用方式也跟 JavaScript 大同小異。
唯一比較特別的是,在我的地圖上的 Marker 都是客製的 Marker,繼承 GMSMarker,並取代其 iconView 即可,只是在算中心點位置時要特別注意 groundAnchor 的算法。
在 Marker 的動畫上,我則練習了 CAAnimationGroup 的用法,並且使用 CAMediaTimingFunction 來呈現動畫的效果,不過我對 iOS App 的 UI 效能還沒有很熟,所以我也不知道我的作法會不會有效能上的問題就是了XD
送審 - Reject
最後送審了!
其實我是按照「iOS App 上架: 一步一腳印的新手教學和更新流程 - AppCoda」這篇的步驟完成的,以上都順利,只是還是被 Reject 了一次,但好像第一次都被 Reject 好像都是正常的XD?
被 Reject 的原因是 Privacy - Location When In Use Usage Description 的原因沒寫清楚,若要取得使用者的位置資訊,那你就必須寫清楚是在 App 上的哪個功能使用,我原本是寫 讓白沙屯媽祖取得你的位置吧! 所以就被 Reject,但改成 若允許取用您的位置,地圖上就可以顯示您與媽祖的相對位置,並且可以查看自己所在的地點。 就審核通過啦!
不過意外的小插曲是,第一次送審雖然被 Reject 了,不過我從 Reject 的訊息中看到 Apple 的截圖才發現我送錯版了,看到截圖中怎會有測試站的資料,才發現我在 Archive 時,沒有調整 Scheme,所以把測試版拿去送審了,不過剛好與 Privacy - Location When In Use Usage Description 的問題一起重新送審!
小結論
以上很趕,短短一個月,所以還有很多東西沒做到完美,例如:效能、有效的 Debug
以後若有開發更進階的有趣的 App 我也會再分享,文章中若有錯誤觀念或者寫法,再麻煩指正,感謝 >"<"
以上參考
- https://gps.godmaps.tw/
- https://www.appcoda.com.tw/ios-app-submission/
- https://www.appcoda.com.tw/intermediate-swift-tips/
- https://stackoverflow.com/questions/29311093/place-activity-indicator-over-uitable-view
- http://mchoe.github.io/SwiftSVG/
- https://github.com/Alamofire/Alamofire
持續改進
今年發現其實很多信徒在活動現場會需要各種服務,如:接送、洗澡、住宿… 等,今年在聊天室內可以看到大量的需求。
今年我堅決不讓大家在上面提供電話,主要是我們沒有規劃好這塊的細節,深怕我們平台會讓不法份子在聊天室內欺負了信眾,於是才採取隱藏電話號碼的措施,明年我們會加強其他的功能來補足這塊的不足!
我們還有很多可以加強的,進步的動力最主要還是支持我們的信眾,因為你們的幫忙分享、給五顆星星,讓團隊動力滿滿!在此我們真心感謝每一位安裝我們 App 的用戶!
最後感謝
感謝幫助過我們的夥伴 吳政賢、李永裕、洪大、小瑋風城、凃嘉文、林啟元… 等各位的幫忙,一路之上幫助我們的人太多了,這邊無法逐字一一感謝,因為你們的幫忙,讓我們每一年的活動可以持續下去!
- 文章作者:吳政賢
- 文章日期:2019年 4月 19日
- 白沙屯 GPS 即時定位臉書:https://www.facebook.com/baishatunGPS
- 原始文章:https://www.facebook.com/notes/663638857892214/