iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0

【Day 11】Swift UI - MapKit 與 CoreLocation 的使用

tags: 釣魚術 swift swiftui CoreLocation Map

本日目標

  • 在地圖上面擺放一顆按鈕,按一下,即取得當前所在位置經緯度,並且更新地圖呈現位置

摘要

  • 對於有拖延症的人來說,非到最後關頭,絕不輕易交卷。
  • 每天都寫一點功能,還蠻碰運氣的,今天時間有點不太夠用,只好先寫一部分。
  • 來談談 iOS 擷取 GPS 座標的方法。

開發筆記

  • 昨天我們指定了地圖預設的座標和尺規之後
  • 今天接著要來完成擷取 GPS 座標的方式
  • 預計下一個功能為在地圖上標記位置圖釘、叫出選單功能

Core Location

  • Obtain the geographic location and orientation of a device.
  • 簡單的說就是擷取經緯度和電子羅盤的資料相關的工具會擺在這裡面。

CLLocationManager

  • The object that you use to start and stop the delivery of location-related events to your app.
  • 用來啟用/停用傳遞地理資訊資料的 object

開發概念與原則

  • 昨天我僅透過傳遞經緯度,直接呈現地圖。
    • 沒有狀態更動 -> 經緯度始終如一
    • 沒有尺規縮放 -> 就沒有人沒有程式對地圖操作咩
  • 今天的需求不一樣了,要偵測數值、移動與縮放地圖!
    • 需要在表層放一個按鈕
    • 需要呼喚感測器讀取經緯度資料
    • 需要讓 Map 圖層讀取到新的變數
  • 需要反覆按按鈕、讀資料、改內容的話,勢必是需要一個狀態變數來存放 經緯度
  • 考慮我之後還要做集郵冊和記錄釣場的功能,意味著在不同的 View 中都會使用到經緯度等資料,那就會偏好採用 class 方式,來存取經緯度的內容。

主要原始碼

  • 因為我還沒有做過類似的功能,程式碼是參考網路範例後做修改
  • 解釋內容前,觀察這個程式碼,那個 class 長得真像 Java
final class FishingLocationModel: NSObject, ObservableObject, CLLocationManagerDelegate
final class FishingLocationModel: NSObject, ObservableObject, CLLocationManagerDelegate {

    @Published var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 25.1125, longitude: 121.4582),
        span: MKCoordinateSpan(latitudeDelta: 0.008, longitudeDelta: 0.008))

    let locationManager = CLLocationManager()
    // 先宣告 locationManager 是 CLLocationManager() 的 instance

    override init() {    // 改寫 init 函式
        super.init()    // 先繼承原 init()
        locationManager.delegate = self  //再加上 locationManager.delegate
    }

    // 弄出一條讓按鈕按按下事件呼叫的函式
    func requestAllowOnceLocationPermission() {
        locationManager.requestLocation()
    }

參考

CLLocationManagerDelegate

  • The methods that you use to receive events from an associated location manager object.
  • 當 manager 的 requestLocation() 被呼叫後,從 Handler 去收取結果。
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let latestLocation = locations.first else {
            return
        }
        
        DispatchQueue.main.async {
            self.region = MKCoordinateRegion(
                center: latestLocation.coordinate,
                span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
            print("Region --> \(self.region)")
        }
    }
    
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error.localizedDescription)
    }
}

下回分曉


上一篇
【Day 10】Swift UI - Map Kit 實作釣點地圖功能
下一篇
【Day 12】Swift Property Wrapper 與物件導向開發的關聯
系列文
無法成為釣魚大師也要努力摸魚!!辣個吃魚神器 APP38
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言