Skip to content

Instantly share code, notes, and snippets.

@ankushkushwaha
Created January 3, 2025 09:32

Revisions

  1. ankushkushwaha created this gist Jan 3, 2025.
    89 changes: 89 additions & 0 deletions MapKitView.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    import SwiftUI
    import MapKit

    struct MapKitView: View {
    @State private var selectedResult: MKMapItem?
    @State private var route: MKRoute?
    @State private var markerCoordinate: CLLocationCoordinate2D
    @State private var timer: Timer?
    @State private var pathCoordinates: [CLLocationCoordinate2D] = []
    @State private var currentIndex: Int = 0

    private let startingPoint = CLLocationCoordinate2D(
    latitude: 40.83657722488077,
    longitude: 14.306896671048852
    )

    private let destinationCoordinates = CLLocationCoordinate2D(
    latitude: 40.849761,
    longitude: 14.263364
    )

    init() {
    markerCoordinate = startingPoint
    }
    var body: some View {
    Map(selection: $selectedResult) {
    // Adding the marker for the current position
    Marker("Moving", coordinate: markerCoordinate)

    // Show the route if it is available
    if let route {
    MapPolyline(route)
    .stroke(.blue, lineWidth: 5)
    }
    }
    .onChange(of: selectedResult) {
    getDirections()
    }
    .onAppear {
    self.markerCoordinate = startingPoint
    self.selectedResult = MKMapItem(placemark: MKPlacemark(coordinate: self.destinationCoordinates))
    }
    }

    func getDirections() {
    self.route = nil

    // Check if there is a selected result
    guard let selectedResult else { return }

    // Create and configure the request
    let request = MKDirections.Request()
    request.source = MKMapItem(placemark: MKPlacemark(coordinate: self.startingPoint))
    request.destination = self.selectedResult

    // Get the directions based on the request
    Task {
    let directions = MKDirections(request: request)
    let response = try? await directions.calculate()
    route = response?.routes.first
    if let polyline = route?.polyline {
    extractCoordinates(from: polyline)
    animateMarker()
    }
    }
    }

    func extractCoordinates(from polyline: MKPolyline) {
    pathCoordinates = []
    for i in 0..<polyline.pointCount {
    let point = polyline.points()[i]
    pathCoordinates.append(CLLocationCoordinate2D(latitude: point.coordinate.latitude, longitude: point.coordinate.longitude))
    }
    }

    func animateMarker() {
    timer?.invalidate()
    currentIndex = 0

    timer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { _ in
    guard currentIndex < pathCoordinates.count else {
    timer?.invalidate()
    return
    }
    markerCoordinate = pathCoordinates[currentIndex]
    currentIndex += 1
    }
    }
    }