I am trying to create my first app, it is an app that allows me to follow the progress of my enduro (dirt bike) sessions, both in race and training mode, it happens that one of the basic features that my app must have is a tracking system on a map so that it saves my route. I am trying to implement the map in my app but I find several errors, I want to apologize if the format or anything i’m writing here is incorrect, this is my first time asking here.
I’m using Xcode 15.4 and iOS 17.5,
Thank you so much for your time.
import SwiftUI
import MapKit
struct IdentifiableCoordinate: Identifiable {
let id = UUID()
let coordinate: CLLocationCoordinate2D
}
struct SecondView: View {
@StateObject private var locationManager = LocationManager()
var body: some View {
ZStack {
Map(coordinateRegion: $locationManager.region, showsUserLocation: true, annotationItems: locationManager.trackingLocations) { location in ( here is the error message: Initializer 'init(coordinateRegion:interactionModes:showsUserLocation:userTrackingMode:annotationItems:annotationContent:)' requires that 'Annotation<Text, some View>' conform to 'MapAnnotationProtocol'
Annotation(location.coordinate, coordinate: <#CLLocationCoordinate2D#>) { ( here is the second error message: Initializer 'init(_:coordinate:anchor:content:)' requires that 'CLLocationCoordinate2D' conform to 'StringProtocol'
Circle()
.strokeBorder(Color.red, lineWidth: 2)
.frame(width: 30, height: 30)
}
}
.ignoresSafeArea()
.onAppear {
locationManager.checkIfLocationServicesIsEnabled()
}
VStack {
Text("ENDURapp")
.font(.largeTitle)
.foregroundColor(.white)
.padding(.top, 50)
Spacer()
}
}
}
}
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
@Published var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194), // Coordenada inicial
span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
)
@Published var trackingLocations: [IdentifiableCoordinate] = []
override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func checkIfLocationServicesIsEnabled() {
if CLLocationManager.locationServicesEnabled() {
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
} else {
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let latestLocation = locations.last else { return }
region = MKCoordinateRegion(
center: latestLocation.coordinate,
span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
)
trackingLocations.append(IdentifiableCoordinate(coordinate: latestLocation.coordinate))
}
}
struct SecondView_Previews: PreviewProvider {
static var previews: some View {
SecondView()
}
}
I change as someone suggest the following: don’t use a ForEach use annotationItems with Map but that didn’t work either.
The errors you are seeing are related to using incompatible APIs. Try replacing Annotation
with MapAnnotation
and the code will compile. If you have a target lower than iOS 17, you have to use the older deprecated types.
For an example on how to use the iOS 17.0+ Annotation
type, the tutorial Integrating MapKit with SwiftUI provides a pretty good introduction.
There are several other issues in the code you shared. A non-exhaustive list:
- The
LocationManager
should be held as a@State private var locationManager = LocationManager()
rather than a state object - Instead of using
CLLocationManager.locationServicesEnabled()
, check the status such as
if locationManager.authorizationStatus == .notDetermined {
locationManager.requestWhenInUseAuthorization()
}