Binding<CLLocation> does not have distance method

MapView.swift

import SwiftUI
import MapKit
import BackgroundTasks


struct MapView: View {
    @StateObject var manager = LocationManager()
    @State var trackingMode: MapUserTrackingMode = .follow
    
    @State private var tracking = true
    
    let annotations: [RunAnnotation] = [];
    @State private var distance: Double = 0.0;
    
    let timer = Timer.publish(every: 3, on: .current, in: .common).autoconnect();
    
        
    var body: some View {
        VStack {
            Map(
                coordinateRegion: $manager.region,
                interactionModes: .all,
                showsUserLocation: true,
                userTrackingMode: $trackingMode,
            ) { annotation in
                MapPin(coordinate: annotation.location)
            }.onReceive(timer, perform: { _ in
                var sumOfDistances = 0.0;
                let stack = $manager.locationStack[0]
                
                print(type(of: $manager.$locationStack)) // Binding<Publisher>
                print(type(of: $manager.locationStack)) // Binding<Array<CLLocation>>
                print(type(of: manager.$locationStack)) // Publisher
                print(type(of: manager.locationStack)) // Array<CLLocation>
                print(type(of: stack)) // Binding<CLLocation>
                
                self.distance = sumOfDistances / 1000
            })
            HStack {
                Toggle("start/stop", isOn: $tracking)
                    .onChange(of: tracking) { value in
                        if (!value) {
                            self.distance = 0.0
                            manager.vacateLocationStack()
                        }
                    }
                Text("\(self.distance)km")
            }
        }
    }
}

LocationManager.swift

 import UIKit
 import MapKit
 import CoreLocation
 import SwiftUI
 
 class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {
     @Published var region = MKCoordinateRegion()
     @Published var locationStack = [ CLLocation ]()
     
     func vacateLocationStack() {
         locationStack = [CLLocation]()
     }
     
     private let manager = CLLocationManager()
     
     override init() {
         super.init()
         manager.delegate = self
         manager.desiredAccuracy = kCLLocationAccuracyBest
         manager.requestAlwaysAuthorization()
         manager.startUpdatingLocation()
     }
     
     func locationManager(
         _ manager: CLLocationManager,
         didUpdateLocations locations: [CLLocation]
     ) {
         self.locationStack.append(contentsOf: locations)
         let encoder = JSONEncoder()
         encoder.outputFormatting = .prettyPrinted
         let jsonData = try! encoder.encode(locations)
     }
 }

I can't CLLocation.distance method at MapView > onReceive function
but it has coordinate, speed, altitude properties

Binding uses dynamicMemberLookup to make its Value's properties available. As KeyPaths can only reference properties on a type, not methods, dynamicMemberLookup is unable to surface methods.

Binding has a wrappedValue property to give you direct access to its value, allowing you to call locationBinding.wrappedValue.distance(...)

3 Likes