1 Reply
      Latest reply on Jul 9, 2019 3:12 AM by Claude31
      sdafsadferf Level 1 Level 1 (0 points)

        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)
                    }
                }
            }