Post not yet marked as solved
Post marked as unsolved with 1 replies, 868 views
Creating an app where as the user walks around the geofenced areas will appear and disappear from the map based on distance. Once in a fenced area the user will be able to listen to audio.The app works as expected when the fenced areas are spaced out quite a bit, but once the geofences overlap the delegates didenterregion and didexitregion never get called. Tried changing the distance, the accuracy and logic with no success.MapViewController // MARK: - MAP PERMISSIONS AND LOCATION MANAGER SETUP
func checkLocationPermission() {
if status == .denied || status == .restricted {
print("Location services not authorized")
} else {
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.activityType = .otherNavigation
locationManager.requestAlwaysAuthorization()
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.delegate = self
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
locationManager.startUpdatingHeading()
}
}
if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
for hap in viewPresenter.hapArray {
let center = CLLocationCoordinate2D(latitude: hap.latitude ?? 0, longitude: hap.longitude ?? 0)
let region = CLCircularRegion(center: center, radius: hap.radius ?? 0, identifier: hap.title ?? "")
region.notifyOnEntry = true
region.notifyOnExit = true
regions.append(region)
}
for region in regions {
locationManager.startMonitoring(for: region)
}
}
}
// MARK: - LOCATION SERVICES DELEGATES
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
viewPresenter.addHapsToMapView(mapView: mapView, manager: manager)
viewPresenter.removeHapFromMap(mapView: mapView, manager: manager)
}
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?,
withError error: Error) {
print("Monitoring failed for region with identifier: \(region!.identifier)")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location Manager failed with the following error: \(error)")
let alert = UIAlertController(title: "Location Manager failed", message: "Uh oh! Our Haps aren't loading right now. \u{1F602} Once you get a signal you can hear something new shortly!", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
locationManager.stopMonitoringSignificantLocationChanges()
locationManager.stopUpdatingLocation()
}
//MARK: - GEOLOCATION DELEGATES
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
MapViewController.didLeaveArea = false
if UIApplication.shared.applicationState == .background {
viewPresenter.sendNotification()
}
if !viewPresenter.haveVisitedHapBefore(title: region.identifier) {
viewPresenter.getCurrentHapFromGeolocation(id: region.identifier)
navigationItem.rightBarButtonItem?.image = imageLiteral(resourceName: "play").resizeImage(CGSize(width: 30, height: 30))
popupMainImage.image = viewPresenter.current?.image8
popupCategoryImage.image = UIImage(named: viewPresenter.current?.category ?? "")
popupCategoryImage.image = popupCategoryImage.image?.withRenderingMode(.alwaysTemplate)
popupCategoryImage.tintColor = .white
popupTitleLabel.createAttributedString(str: "You have a Hap!", fontName: "LeagueSpartan-Bold", fontSize: 25, color: .white)
popupSecondaryLabel.createAttributedString(str: viewPresenter.current?.title ?? "", fontName: "Arimo", fontSize: 15, color: .white)
popupTopConstraint.constant = 0
UIView.animate(withDuration: 1.0, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
player?.stop()
MapViewController.didLeaveArea = true
popupTopConstraint.constant = -250
navigationItem.rightBarButtonItem?.image = imageLiteral(resourceName: "forwardArrow")
UIView.animate(withDuration: 1.0, animations: { () -> Void in
self.view.layoutIfNeeded()
})
viewPresenter.vistedHaps.append(viewPresenter.annotationTitle ?? "")
if let playerCheck: Bool = MediaPlayerViewController.player?.isPlaying {
if !playerCheck {
viewPresenter.current = nil
}
}
}ViewPresenter
// MARK: - SET UP ANNOTATIONS FOR MAP
func addHapsToMapView(mapView: MKMapView, manager: CLLocationManager) {
Haps.shared.hapArray.forEach { hap in
guard let managerCoordinates: CLLocationCoordinate2D = manager.location?.coordinate else { return }
let userLocation: CLLocation = CLLocation(latitude: managerCoordinates.latitude, longitude: managerCoordinates.longitude)
let hapLocation = CLLocation(latitude: hap.latitude ?? 0, longitude: hap.longitude ?? 0)
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: hap.latitude ?? 0, longitude: hap.longitude ?? 0)
annotation.title = hap.title
if userLocation.distance(from: hapLocation) < 600 && checkAnnotations(annotation: annotation, mapView: mapView) && !haveVisitedHapBefore(title: hap.title ?? "") {
mapView.addAnnotation(annotation)
annotationTitle = annotation.title
}
}
}
// MARK: - CHECKS IF ANNOTATION IS ALREADY ON MAP
func checkAnnotations(annotation: MKPointAnnotation, mapView: MKMapView) -> Bool {
for item in mapView.annotations {
if item.coordinate.latitude == annotation.coordinate.latitude && item.coordinate.longitude == annotation.coordinate.longitude {
return false
}
}
return true
}
// MARK: - REMOVES HAP FROM MAP
func removeHapFromMap(mapView: MKMapView, manager: CLLocationManager) {
guard let managerCoordinates: CLLocationCoordinate2D = manager.location?.coordinate else { return }
let userLocation: CLLocation = CLLocation(latitude: managerCoordinates.latitude, longitude: managerCoordinates.longitude)
for annotation in mapView.annotations {
let annotationDistance: CLLocation = CLLocation(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude)
if userLocation.distance(from: annotationDistance) > 600 {
mapView.removeAnnotation(annotation)
}
}
}