I am working on a map app in Xcode 15.4.
Everything works except when I reference the @MainActor class LocationManager {} in the private var locationManager
I get the following error:
Main actor-isolated static property 'shared' can not be referenced from a non-isolated context; this is an error in Swift 6
I am new to Swift 6 and could use some guidance resolving this issue.
Here is the code:
import SwiftUI
import MapKit
@MainActor class LocationManager {
static let shared = LocationManager()
let manager: CLLocationManager
init() {
self.manager = CLLocationManager()
if self.manager.authorizationStatus == .notDetermined {
self.manager.requestWhenInUseAuthorization()
}
}
}
extension CLLocationCoordinate2D {
static var notreDam: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: 48.853218898078126, longitude:2.349977679044624)
}
static var saintGermain: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: 48.854184067183304, longitude:2.334469956279526)
}
static var saintDenis: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: 48.93693647702151, longitude:2.3565013545150872)
}
static var saintEustach: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: 48.86350319977858, longitude:2.345539521410205)
}
static var saintEtienne: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: 48.846708620929796, longitude: 2.34847593490404)
}
}
enum MapOptions: String, Identifiable, CaseIterable {
case standard
case hybrid
case imagery
var id: String {
self.rawValue
}
var mapStyle: MapStyle {
switch self {
case .standard:
return .standard
case .hybrid:
return .hybrid
case .imagery:
return .imagery
}
}
}
struct ContentView: View {
private var locationManager = LocationManager.shared
@State private var selectedMapOption: MapOptions = .standard
var body: some View {
ZStack(alignment: .top) {
Map {
Annotation("Notre Dame", coordinate: .notreDam) {
Image(systemName: "house.circle.fill")
.padding(4)
.background(.red)
.foregroundColor(.white)
.cornerRadius(20.0)
}
Annotation("Saint Germain", coordinate: .saintGermain) {
Image(systemName: "house.circle.fill")
.padding(4)
.background(.red)
.foregroundColor(.white)
.cornerRadius(20.0)
}
Annotation("Saint Denis", coordinate: .saintDenis) {
Image(systemName: "house.circle.fill")
.padding(4)
.background(.red)
.foregroundColor(.white)
.cornerRadius(20.0)
}
Annotation("Saint Eustache", coordinate: .saintEustach) {
Image(systemName: "house.circle.fill")
.padding(4)
.background(.red)
.foregroundColor(.white)
.cornerRadius(20.0)
}
Annotation("Saint Etienne", coordinate: .saintEtienne) {
Image(systemName: "house.circle.fill")
.padding(4)
.background(.red)
.foregroundColor(.white)
.cornerRadius(20.0)
}
UserAnnotation()
}.mapStyle(selectedMapOption.mapStyle)
Picker("Map Styles", selection: $selectedMapOption) {
ForEach(MapOptions.allCases) { mapOption in
Text(mapOption.rawValue.capitalized).tag(mapOption)
}
}.pickerStyle(.segmented)
.background(.white)
.padding()
}
}
}
#Preview {
ContentView()
}
One easy way is to annotate the ContentView
with @MainActor
- thus the context where the shared instance is used becomes main actor-isolated.
When you move to Xcode 16 and Swift 6, View is marked with @MainActor
so this warning will be gone by then.
See What’s new in SwiftUI - WWDC 2024 around 17:30.