Location manager stops updating location - swift3

I am having a problem while updating the user location. I am building app which is show the nearest trashcans and the distance between them and the user. I am using this locationmanager but it never updates the location. Even when the user moves, the stored locations stay the same
let manager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location: CLLocation = locations.last!
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
//store myLocation in UserDefaults
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.latitude, forKey: "latitude")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.longitude, forKey: "longitude")
UserDefaults.standard.set(myLocation.latitude, forKey: "latitude")
UserDefaults.standard.set(myLocation.longitude, forKey: "longitude")
UserDefaults().synchronize()
self.mapView.showsUserLocation = true
}
I am using this to calculate the distance
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "latitude") as! CLLocationDegrees, UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "longitude") as! CLLocationDegrees)
// geeft zin met afstand van locatie1 tot myLocation
func afstandPuntTotUser(locatie1: CLLocationCoordinate2D) -> String {
manager.startUpdatingLocation()
let cllocatie1 = converter(locatie: locatie1)
let myLocation = converter(locatie: myLocation)
let afstand = cllocatie1.distance(from: myLocation)
let afgerondeafstand = afstand - afstand.truncatingRemainder(dividingBy: 1.0) //zorgt voor 1 kommagetal
if afstand < 1000.0 {
return "De afstand tot de bak is \(afgerondeafstand) meter"
}
else {
return "De afstand tot de bak is \(afgerondeafstand / 1000 - (afgerondeafstand / 1000).truncatingRemainder(dividingBy: 0.1)) kilometer"
}
}
inside the app this isn't a very big problem, but I need a constantly updated location in order for the widget to work properly. This widget shows the three nearest trashcans and doesn't really do what it is supposed to do if it is using old location data.
here is my complete ViewController:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
let manager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location: CLLocation = locations[0]
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
//let span: MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
//let region: MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
//store myLocation in UserDefauls
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.latitude, forKey: "latitude")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.longitude, forKey: "longitude")
UserDefaults.standard.set(myLocation.latitude, forKey: "latitude")
UserDefaults.standard.set(myLocation.longitude, forKey: "longitude")
UserDefaults().synchronize()
//region wel of niet? nog even over hebben
//mapView.setRegion(region, animated: true)
self.mapView.showsUserLocation = true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
//maakt van CLLocationCoordinate een CLLocation
func converter(locatie: CLLocationCoordinate2D) -> CLLocation {
let latitude = locatie.latitude
let longitude = locatie.longitude
return CLLocation(latitude: latitude, longitude: longitude)
}
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(UserDefaults.standard.value(forKey: "latitude") as! CLLocationDegrees, UserDefaults.standard.value(forKey: "longitude") as! CLLocationDegrees)
//let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "latitude") as! CLLocationDegrees, UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "longitude") as! CLLocationDegrees)
// geeft zin met afstand van locatie1 tot myLocation
func afstandPuntTotUser(locatie1: CLLocationCoordinate2D) -> String {
let cllocatie1 = converter(locatie: locatie1)
let myLocation = converter(locatie: myLocation)
let afstand = cllocatie1.distance(from: myLocation)
let afgerondeafstand = afstand - afstand.truncatingRemainder(dividingBy: 1.0) //zorgt voor 1 kommagetal
if afstand < 1000.0 {
return "De afstand tot de bak is \(afgerondeafstand) meter"
}
else {
return "De afstand tot de bak is \(afgerondeafstand / 1000 - (afgerondeafstand / 1000).truncatingRemainder(dividingBy: 0.1)) kilometer"
}
}
//geeft puur afstand van locatie1 tot myLocation
func distanceForWidget(locatie1: CLLocationCoordinate2D) -> String {
let cllocatie1 = converter(locatie: locatie1)
let myLocation = converter(locatie: myLocation)
let afstand = cllocatie1.distance(from: myLocation)
let meters = afstand as Double - afstand.truncatingRemainder(dividingBy: 1.0) as Double
let kilometers = afstand / 1000 - (afstand / 1000).truncatingRemainder(dividingBy: 0.1)
if afstand < 1000.0 {
return "\(meters) m"
}
else {
return "\(kilometers) km"
}
}
//voegt snel een afvalbakpin toe
func addAfvalbak(pinLocatie: CLLocationCoordinate2D) -> MKAnnotation {
return purePin(title: "Afvalbak", subtitle: afstandPuntTotUser(locatie1: pinLocatie), coordinate: pinLocatie) as MKAnnotation
}
//voegt sel een glasbakpin toe
func addGlasbak(pinLocatie:CLLocationCoordinate2D) -> MKAnnotation {
return purePin(title: "Glasbak", subtitle: afstandPuntTotUser(locatie1: pinLocatie), coordinate: pinLocatie)
}
//voegt snel een blikvangerpin toe
func addBlikvanger(pinLocatie:CLLocationCoordinate2D) -> MKAnnotation {
return purePin(title: "Blikvanger", subtitle: afstandPuntTotUser(locatie1: pinLocatie), coordinate: pinLocatie)
}
//voegt snel een volledige afvalbak pin + afstand toe
func addFullAfvalbak(pinlocatie: CLLocationCoordinate2D) -> fullPin {
return fullPin(title: "Afvalbak", subtitle: afstandPuntTotUser(locatie1: pinlocatie), coordinate: pinlocatie)
}
//voegt snel een volledige glasbak pin + afstand toe
func addFullGlasbak(pinlocatie: CLLocationCoordinate2D) -> fullPin {
return fullPin(title: "Glasbak", subtitle: afstandPuntTotUser(locatie1: pinlocatie), coordinate: pinlocatie)
}
//voegt snel een volledige blikvanger pin + afstand toe
func addFullBlikvanger(pinlocatie: CLLocationCoordinate2D) -> fullPin {
return fullPin(title: "Blikvanger", subtitle: afstandPuntTotUser(locatie1: pinlocatie), coordinate: pinlocatie)
}
//array met alle afvalbaklocaties
let afvalbakLocaties: [CLLocationCoordinate2D] = [jacobbotkeweg1, jacobbotkeweg2, jacobbotkeweg3, jacobbotkeweg4, jacobbotkeweg5, jacobbotkeweg6, jacobbotkeweg7, aldlansdyk1, aldlansdyk2, aldlansdyk3, weideflora1, weideflora2, hempensweg1, hempensweg2, hempensweg3, hempensweg4, hempenserweg1, hempenserweg2, hempenserweg3, legedyk1, verlengdeschrans1, oostergoweg1, henridunantweg1, henridunantweg2, henridunantweg3, henridunantweg4, henridunantweg5, henridunantweg6, henridunantweg7, abbingapark1, abbingapark2, tijnjedyk1, tijnjedyk2, tijnjedyk3, tijnjedyk4, ipebrouwerssteeg1, nieuwestad1, nieuwestad2, nieuwestad3, nieuwestad4, nieuwestad5, nieuwestad6, nieuwestad7, nieuwestad8, nieuwestad9, nieuwestad10, nieuwestad11, nieuwestad12]
//array met alle glasbaklocaties
let glasbakLocaties: [CLLocationCoordinate2D] = [timothee1]
//array met alle blikvangerlocaties
let blikvangerLocaties: [CLLocationCoordinate2D] = [bitgummerdyk1]
//slaat alle locaties op voor widget
//UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(afvalbakLocaties, forKey: "afvalbakLocaties")
//UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(glasbakLocaties, forKey: "glasbakLocaties")
//UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(blikvangerLocaties, forKey: "blikvangerLocaties")
//array met alle pinnen die worden toegevoegd
var allePinnen: [MKAnnotation] = []
//voegt alle afvalbakken toe aan allePinnen
for item in afvalbakLocaties {
allePinnen.append(addAfvalbak(pinLocatie: item))
}
//voegt alle glasbakken toe aan allePinnen
for item in glasbakLocaties {
allePinnen.append(addGlasbak(pinLocatie: item))
}
//voegt alle blikvangers toe aan allePinnen
for item in blikvangerLocaties {
allePinnen.append(addBlikvanger(pinLocatie: item))
}
//voegt alle pinnen toe aan de kaart
mapView.addAnnotations(allePinnen)
var fullPinnen:[fullPin] = []
//voegt alle afvalbakken toe aan fullPinnen
for item in afvalbakLocaties {
fullPinnen.append(addFullAfvalbak(pinlocatie: item))
}
//voegt alle glasbakken toe aan fullPinnen
for item in glasbakLocaties {
fullPinnen.append(addFullGlasbak(pinlocatie: item))
}
//voegt alle blikvangers toe aan fullPinnen
for item in blikvangerLocaties {
fullPinnen.append(addFullBlikvanger(pinlocatie: item))
}
//sorteert de bakken in fullPinnen op afstand
fullPinnen.sort {$0.afstand < $1.afstand}
//slaat de 3 dichtsbijzijnde afvalbakken op
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")!.set(fullPinnen[0].afstand, forKey: "closestpin1afstand")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(fullPinnen[0].title, forKey: "closestpin1naam")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")!.set(fullPinnen[1].afstand, forKey: "closestpin2afstand")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(fullPinnen[1].title, forKey: "closestpin2naam")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")!.set(fullPinnen[2].afstand, forKey: "closestpin3afstand")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(fullPinnen[2].title, forKey: "closestpin3naam")
UserDefaults().synchronize()

Create a new class in the same Project and add this code in your new class. Then check whether your didUpdateLocations method will called or not. And let me know whether this code will work for you or not.
#IBOutlet weak var mapView: MKMapView!
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
// Do any additional setup after loading the view, typically from a nib.
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location: CLLocation = locations[0]
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
//let span: MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
//let region: MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
//store myLocation in UserDefauls
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.latitude, forKey: "latitude")
UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.longitude, forKey: "longitude")
UserDefaults.standard.set(myLocation.latitude, forKey: "latitude")
UserDefaults.standard.set(myLocation.longitude, forKey: "longitude")
UserDefaults().synchronize()
//region wel of niet? nog even over hebben
//mapView.setRegion(region, animated: true)
self.mapView.showsUserLocation = true
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Failed to find user's location: \(error.localizedDescription)")
}

Check the following:
Enable background modes and select location updates in you app targets's capabilities section.
Add NSLocationUsageDescription in your app info plist file.
Add Privacy - Location Always Usage Description in your info plist if you will use the location service while the app is in background or not running else add Privacy - Location When In Use Usage Description if you will only use the location service while the user uses your app.

Related

MapView does not show user current location

I was trying to display my current location into a Swiftui MapView. To do so, I created the following class:
import SwiftUI
import CoreLocation
import Combine
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
#Published var locationManager = CLLocationManager()
#Published var locationStatus: CLAuthorizationStatus?
#Published var lastLocation: CLLocation?
override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
private var statusString: String {
guard let status = locationStatus else {
return "unknown"
}
switch status {
case .notDetermined: return "notDetermined"
case .authorizedWhenInUse: return "authorizedWhenInUse"
case .authorizedAlways: return "authorizedAlways"
case .restricted: return "restricted"
case .denied: return "denied"
default: return "unknown"
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
locationStatus = status
print(#function, statusString)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else { return }
lastLocation = location
// fetchLocation(location: lastLocation)
self.locationManager.stopUpdatingLocation()
print(#function, location)
}
}
and the following view:
var body: some View {
VStack {
Text("Latitude: \(locationManager.lastLocation?.coordinate.latitude ?? 0), Longitude: \(locationManager.lastLocation?.coordinate.longitude ?? 0)")
.onAppear{
print("DEBUG: status 1 : \(locationManager.lastLocation?.coordinate.latitude ?? 0)")
}
MapView(lat: (locationManager.lastLocation?.coordinate.latitude ?? 0), lon: locationManager.lastLocation?.coordinate.longitude ?? 0, latDelta: 0.05, lonDelta: 0.05)
.frame(width: UIScreen.screenWidth - 36, height: UIScreen.screenWidth / 2)
.cornerRadius(10)
.onAppear{
print("DEBUG: status 2 : \(locationManager.locationStatus)")
print("DEBUG: lat: \(locationManager.lastLocation?.coordinate.latitude), lon: \(locationManager.lastLocation?.coordinate.longitude)")
}
}
}
So far, the Textfield does show the correct coordinates, but my Mapview shows NIL as the coordinates.
Adding my MapView here as well for completeness:
struct MapView: UIViewRepresentable {
#State var lat = 0.0
#State var lon = 0.0
#State var latDelta = 0.05
#State var lonDelta = 0.05
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ uiView: MKMapView, context: Context) {
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon )
let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)
let region = MKCoordinateRegion(center: coordinate, span: span)
uiView.setRegion(region, animated: true)
}
}
Hope you could have a look and see if I have missed anything.
The answer is:
Remove all the #State from the MapView():
struct MapView: UIViewRepresentable {
var lat = 0.0
var lon = 0.0
var latDelta = 0.05
var lonDelta = 0.05
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ uiView: MKMapView, context: Context) {
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon )
let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)
let region = MKCoordinateRegion(center: coordinate, span: span)
uiView.setRegion(region, animated: true)
}
}

SwiftUI - MKMapView - Display map center coordinate in a #EnvironmentObject variable

can someone please help me with my problem?
I have a SwiftUI Project and wrote a MKMapView File. I would like to store the Center coordinates in a #EnvironmentObject variable.
Unfortunately, I can't manage to pack the center coordinates into the EnvironmentObject variable.
my code looks like this:
struct MapView: UIViewRepresentable {
#EnvironmentObject var messpunkt_manager: Messpunkt_Manager
func makeUIView(context: Context) -> MKMapView {
let map = MKMapView()
map.showsUserLocation = true // zeigt den aktuellen Standort des Users
map.delegate = context.coordinator // ermöglich die Bedienung
// shows annotations already in array
for location in messpunkt_manager.messpunkte {
let annotation = MKPointAnnotation()
annotation.title = location.title
annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
map.addAnnotation(annotation)
}
return map
}
func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<MapView>) {
// start coordinates
let coordinate = CLLocationCoordinate2D(latitude: messpunkt_manager.centerCoordinate.latitude, longitude: messpunkt_manager.centerCoordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: messpunkt_manager.centerZoom.latitudeDelta, longitudeDelta: messpunkt_manager.centerZoom.longitudeDelta)
let region = MKCoordinateRegion(center: coordinate, span: span)
uiView.setRegion(region, animated: true)
// Adds annotation to the map
for location in messpunkt_manager.messpunkte {
let annotation = MKPointAnnotation()
annotation.title = location.title
annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
uiView.addAnnotation(annotation)
}
if messpunkt_manager.karteAusgeaehlt == 0 {
uiView.mapType = .standard
}
if messpunkt_manager.karteAusgeaehlt == 1 {
uiView.mapType = .hybrid
}
if messpunkt_manager.karteAusgeaehlt == 2 {
uiView.mapType = .satellite
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
the center coordinates should then be put into this #EnvironmentObject variable
#Published var position = CLLocationCoordinate2D()
thanks for your help!
And sorry for my naming. For me its easier to name the variables, functions ... in my native language German. I hope its not a big deal.
In your class Coordinator you need to set the value. Assuming your coordinator is set up like this:
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
...
}
Then you would add this function:
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
parent. messpunkt_manager.position = mapView.region
}
It is really helpful to post a Minimal Reproducible Example (MRE). As you can see, you left out an important piece

Show user coordinates SwiftUI

I have custom Map with pin on user location. When i need to show user location. I tried use CLLocationManager to show coordinates but they turns 0.0
struct MapView : UIViewRepresentable {
func makeCoordinator() -> MapView.Coordinator {
return MapView.Coordinator(parent1: self)
}
#Binding var title : String
#Binding var subtitle : String
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
let map = MKMapView()
let coordinate = CLLocationCoordinate2D(latitude: 55.757485,
longitude: 37.632179)
map.region = MKCoordinateRegion(center: coordinate,
latitudinalMeters: 100,
longitudinalMeters: 100)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
map.delegate = context.coordinator
map.addAnnotation(annotation)
return map
}
func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<MapView>) {}
class Coordinator: NSObject , MKMapViewDelegate {
var parent : MapView
init(parent1: MapView) {
parent = parent1
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let pin = MKPinAnnotationView(annotation: annotation,
reuseIdentifier: "pin")
pin.isDraggable = true
pin.pinTintColor = .blue
pin.animatesDrop = true
return pin
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationView.DragState, fromOldState oldState: MKAnnotationView.DragState) {
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: (view.annotation?.coordinate.latitude)!,
longitude: (view.annotation?.coordinate.longitude)!)){ (places, err) in
if err != nil {
print((err?.localizedDescription)!)
return
}
self.parent.title = (places?.first?.name ?? places?.first?.postalCode)!
self.parent.subtitle = (places?.first?.locality ?? places?.first?.country ?? "None")
}
}
}
}
There is my start point
let coordinate = CLLocationCoordinate2D(latitude: 55.757485,
longitude: 37.632179)
So i need to add user coordinates in this stroke without asking permit as i have already asked it
All you have to do is make the showsUserLocation var true.(Look at the docs)
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
let map = MKMapView()
let coordinate = CLLocationCoordinate2D(latitude: 55.757485, longitude: 37.632179)
map.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 100, longitudinalMeters: 100)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
// new code...
map.showsUserLocation = true
map.delegate = context.coordinator
map.addAnnotation(annotation)
return map
}
As of iOS 14 you can use the native SwiftUI Map. This might be easier to work with than bridging to UIKit

How to create multiple markers in GoogleMaps with SwiftUI?

I need to add multiple markers in my MapView. How to add multiple markers in same mapview using swiftui?
This is my code:
import SwiftUI
import UIKit
import GoogleMaps
struct MapView: UIViewRepresentable {
let coordinate: CLLocationCoordinate2D?
let marker : GMSMarker = GMSMarker()
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Self.Context) {
marker.position = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
marker.title = "XYZ"
marker.snippet = "ABCD"
marker.map = mapView
}
}
Here is my sample,
struct MapView: UIViewRepresentable {
let coordinate: CLLocationCoordinate2D
let cities = [
[
"name": "Yangon",
"lat": 16.8409,
"long": 96.1735
],
[
"name": "Mandalay",
"lat": 21.9588,
"long": 96.0891
]
]
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Self.Context) {
for city in cities {
let marker : GMSMarker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: city["lat"] as! CLLocationDegrees, longitude: city["long"] as! CLLocationDegrees)
marker.title = city["name"] as? String
marker.snippet = "Welcome to \(city["name"] as! String)"
marker.map = mapView
}
}
}

Could not retrieve region info - monitoring not working

Here's my code. As soon as I fire up the app in Simulator. I see following messages in the debug window.
2020-05-02 23:01:37.931720-0400 SwiftMapView[42245:6851218] Metal API Validation Enabled
2020-05-02 23:01:38.216200-0400 SwiftMapView[42245:6851218] libMobileGestalt MobileGestalt.c:1647: Could not retrieve region info
import SwiftUI
import MapKit
struct MapView: UIViewRepresentable {
var locationManager = CLLocationManager()
func setupManager() {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
// Set Geofencing region
//let locValue:CLLocationCoordinate2D = self.locationManager.location!.coordinate
let locValue:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 15.833826, longitude: 78.845220)
let geofencingRegion: CLCircularRegion = CLCircularRegion(center:locValue, radius: 100, identifier: "Crap")
geofencingRegion.notifyOnExit = true
geofencingRegion.notifyOnEntry = true
// Start monitoring
locationManager.startMonitoring(for: geofencingRegion)
}
func makeUIView(context: Context) -> MKMapView {
setupManager()
let mapView = MKMapView(frame: UIScreen.main.bounds)
//mapView.centerCoordinate = CLLocationCoordinate2D(latitude: 15.833826, longitude: 78.845220)
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// Show current user location
//uiView.showsUserLocation = true
// Requst location when in use
self.locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled()
&& (CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse)
{
//self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.locationManager.startUpdatingLocation()
let locValue:CLLocationCoordinate2D = self.locationManager.location!.coordinate
let coordinate = CLLocationCoordinate2D(latitude: locValue.latitude, longitude: locValue.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: 0)
let region = MKCoordinateRegion(center: coordinate, span: span)
uiView.setRegion(region, animated: true)
}
}
}
class MapAppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
var locationManager: CLLocationManager?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.locationManager = CLLocationManager()
self.locationManager!.delegate = self
return true
}
}
extension MapAppDelegate{
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
print("Hello World")
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
print("Welcome Home")
}
}
In simulator you have to add a location, then your code works for me (at least if your info.plist is correct):