2019 白沙屯媽祖南下進香 GPS 系統 因為每年我都會協助幫忙準備這個「白沙屯媽祖南下進香」的活動,所以今年我也在準備著,一年一次,這個專案每年這時候都會啟動,常常有人會問我,不就是把去年的資料庫清空就好了嗎? 不!因為每一年,在我的技術上都是在進步,於是回頭看去年,總會有哪麼一點點不完美的地方,執著的工…

2019 白沙屯媽祖南下進香 GPS 系統

因為每年我都會協助幫忙準備這個「白沙屯媽祖南下進香」的活動,所以今年我也在準備著,一年一次,這個專案每年這時候都會啟動,常常有人會問我,不就是把去年的資料庫清空就好了嗎?

不!因為每一年,在我的技術上都是在進步,於是回頭看去年,總會有哪麼一點點不完美的地方,執著的工程師個性,就會想要把他重寫,讓這個專案更加完美!

這個專案每年從的資訊工程幾乎都是由我完成的,以下就是這次我個人完成的項目:

都是一個人完成,而這次也加入了開發 iOS App,其實成就感頗高!所以這篇會著重在 iOS Swift 的學習心得,若要看其他部分也可以參考2016 的心得

廢話不多說。寫 App,當然是直接先給鏈結下載呀,有興趣的夥伴歡迎下載囉!

開發心得

回想起當初想學 App 已經是三年前了,當初還是寫 Object-C,但因為本身工作是專職的網站前後端工程師,所以一直沒有時間好好的專研,頂多就是想到就寫個小 App,了解一下推播、Watch App.. 等,但都一直沒上架過,所以就默默的繳了三年的開發者費用,這就是信仰!?(疑)

在今年,我終於上架了我第一個 App

以往這個活動我都是使用網頁技術來呈現,但是從去年開始 Google Maps 就調漲了費用、收費方式,於是不得不另尋他路改採用 App 的方式來省錢,Google Maps 官方也寫了,採用 App SDK 好像基本的地圖就可以無上限使用,所以在今年一月底,我正式開始籌備今年度的 GPS 系統!

這個系統我想對很多資深的工程師來說困難度應該不高,主要就是讀取 API 並且將內容呈現,所以對我來說幾項重點:

  1. UI - Constraint
  2. API - Alamofire
  3. Maps - Google Maps
  4. 送審 - 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 我也會再分享,文章中若有錯誤觀念或者寫法,再麻煩指正,感謝 >"<"

以上參考

自己做自己的 CocoaPods - OA Wu's Blog
自己做自己的 CocoaPods
自己做自己的 CocoaPods 寫到一定程度之後,總會有幾個自己愛用語熟悉的 Lib,那就自己做一下屬於自己的 pod 套件吧! 新增 以下會用 OAPodTest 當作套件名稱範例,各位要做自己的套件請用自己的名稱捏! 由於 pod 套件可與 GitHub 綁定,讓他自動去抓上面的原始碼,所以請先開一個 GitHub repository! 這是我自己的 GitH…
Google Maps 大富翁 - OA Wu's Blog
Google Maps 大富翁
Google Maps 大富翁 這是一個使用 Google Maps JavaScript API 製作的大富翁遊戲!基本上是利用 Google Maps Markers 以及 Polyline 所建置出路線、節點、角色、計分、蓋房... 等設計! 這是一個使用前端 JavaScript、Google Maps 所設計的大富翁遊戲,主要也使用了 jQuery 以及 SCSS 等工具實作,利用 Google Maps Marker…
實作 Instagram Maps 相片地圖 - OA Wu's Blog
實作 Instagram Maps 相片地圖
實作 Instagram Maps 相片地圖 Instagram App 當中有一項很特別的功能是我很喜愛的,就是地圖模式的瀏覽照片,而且 Instagram 將這項功能優化得不錯,使得當地圖縮小時,密集的 Marker 會合成一個 Marker,而這樣的地圖功能在 Google Maps JavaScript API 上可以實作得到! 簡單說,這個專案的目的是利用 Google Mpas 來模…
CatMap - OA Wu's Blog
CatMap
CatMap 此作是我第一個比較完整的 iOS 的 App,主要利用基本的 iOS 元件製作照相上傳、分享、地圖功能,以下是我一些學習的筆記與心得! App 沒什麼主要方向,這就只是個到處模仿的小作品,一開始利用了 TableView,再經由客製化的 TableViewCell 去做出類似 Instagram、Facebook 的動態訊息頁,然後再利用 ImagePickerCon…
吳政賢個人簡歷OA WuLiveCoding.tw
OA Wu's Blog
開發心得
2019 白沙屯媽祖南下進香 GPS 系統