Мониторинг региона iOS не работает

Несколько месяцев я занимался разработкой для iOS, а недавно я разрабатывал приложение для шины. В настоящее время я подражаю движениям автобуса и устанавливаю несколько аннотаций на автобусных остановках. В целях тестирования я настроил только одну автобусную остановку и пытаюсь отслеживать, когда автобус вошел в этот регион и также вышел.

Странно мой didStartMonitoringForRegion метод называется отлично, но ни didEnterRegion ни didExitRegion методы называются. Каждый раз, когда я запускаю программу, автобус в значительной степени проходит остановку, не спрашивая меня об этом.

Может ли кто-нибудь объяснить мне, почему это происходит и как это решить?

let locationManager = CLLocationManager()
var allBusAnnotations = [MKPointAnnotation]()
var summitEastBusStations = [CLLocationCoordinate2D]()
var busStopNames = ["Dix Stadium", "Risman Plaza", "Terrace Drive", "Terrace Drive 2","C-Midway","Theatre Dr.","East Main Street","South Lincoln"]
var radius = 500 as CLLocationDistance

// 0.02 is the best zoom in factor
var mapZoomInFactor : Double = 0.02

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.getBusStop()
    self.locationManager.delegate = self
    // gets the exact location of the user
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
    // gets the user's location only when the app is in use and not background
    self.locationManager.requestWhenInUseAuthorization()
    self.locationManager.startUpdatingLocation()

    self.mapView.showsUserLocation = true
    self.setBusStopAnnotations(summitEastBusStations)
    // self.mapView.mapType = MKMapType.Satellite  
}
    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

    // sends the latitude and longitude to the Apple Servers then returns the address
    CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placeMarks: [AnyObject]!, error: NSError!) -> Void in

        if error != nil
        {
            println("Reverse Geocode Failed: " + error.localizedDescription)
            return
        }

        if placeMarks.count > 0
        {
            // gets the most updated location
            let pm = placeMarks.last as! CLPlacemark

            let centre = CLLocationCoordinate2D(latitude: manager.location.coordinate.latitude, longitude: manager.location.coordinate.longitude)

            // draws a circle in which the map will zoom to
            let region = MKCoordinateRegion(center: centre, span: MKCoordinateSpan(latitudeDelta: self.mapZoomInFactor, longitudeDelta: self.mapZoomInFactor))

            self.mapView.setRegion(region, animated: true)

            self.displayLocationInfo(pm)

            // self.distanceToClosestAnnotation(pm)

            self.geoFencing()

            // YOU CAN IGNORE THIS WHOLE PART. IT'S IRRELEVANT FOR THIS QUESTION
            var repeatTimes = 0
            var count = 0 
            while(count <= 7)
            {
                if count == (self.summitEastBusStations.count - 1)
                {
                    count = 1
                    ++repeatTimes
                }
                else if repeatTimes == 1
                {
                    count = 0
                    ++repeatTimes
                }
                else if repeatTimes == 2
                {
                    break
                }

                self.distanceToBusStop(pm, count: count)
                ++count
            }
        }
    })
}
    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    println("Location Manager Failed: " + error.localizedDescription)
}

func locationManager(manager: CLLocationManager!, didStartMonitoringForRegion region: CLRegion!) {
    println("The region is monitored")
    println("The monitored region is \(region.description)")
}

func locationManager(manager: CLLocationManager!, monitoringDidFailForRegion region: CLRegion!, withError error: NSError!) {
    println("Failed to monitor the stated region")
}

func locationManager(manager: CLLocationManager!, didEnterRegion region: CLRegion!) {
    println("The bus has entered the region")
}

func locationManager(manager: CLLocationManager!, didExitRegion region: CLRegion!) {
    println("The bus has left the region")
}
func geoFencing()
{

    let rismanPlaza = CLLocationCoordinate2D(latitude: 41.1469492, longitude: -81.344068)

    var currentBusStop = CLLocation(latitude: rismanPlaza.latitude, longitude: rismanPlaza.longitude)
    addRadiusCircle(currentBusStop)

    let busStopRegion = CLCircularRegion(center: CLLocationCoordinate2D(latitude: rismanPlaza.latitude, longitude: rismanPlaza.longitude), radius: radius, identifier: busStopNames[1])

    if radius > self.locationManager.maximumRegionMonitoringDistance
    {
        radius = self.locationManager.maximumRegionMonitoringDistance
    }

    locationManager.startMonitoringForRegion(busStopRegion)

}

// creates the radius around the specified location
func addRadiusCircle(location: CLLocation)
{
    self.mapView.delegate = self
    var circle = MKCircle(centerCoordinate: location.coordinate, radius: radius)
    self.mapView.addOverlay(circle)
}

// performs the actual circle colouring
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer!
{
    if overlay is MKCircle
    {
        var circle = MKCircleRenderer(overlay: overlay)
        circle.strokeColor = UIColor.redColor()
        circle.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
        circle.lineWidth = 1
        return circle
    }
    else
    {
        return nil
    }
}

3 ответа

Решение

Я закончил тем, что использовал CLRegion.containsCoordinate(location.coordinate) метод вместо. Это работает примерно так же.

Как только объект вошел в мою заданную область, он возвращает истину, и отсюда я могу знать, когда он вошел и вышел из области.

Пожалуйста убедитесь [CLLocationManager regionMonitoringAvailable] возвращается YES а такжеCLLocationManager.monitoredRegions содержит действительные регионы.

Также из документации Apple:

В iOS 6 регионы с радиусом от 1 до 400 метров работают лучше на устройствах iPhone 4S или новее. (В iOS 5 регионы с радиусом от 1 до 150 метров работают лучше на устройствах iPhone 4S и более поздних версиях.) На этих устройствах приложение может ожидать получения соответствующего введенного региона или уведомления о выходе из региона в среднем в течение 3-5 минут, если не раньше.

А также

Приложения могут ожидать уведомления, как только устройство переместится на 500 метров или более от предыдущего уведомления. Не следует ожидать уведомлений чаще, чем раз в пять минут. Если устройство способно извлекать данные из сети, менеджер местоположения с гораздо большей вероятностью будет своевременно доставлять уведомления.

Есть много причин, по которым ваши делегаты не запускаются. Сначала перейдите к настройкам цели и на вкладке "Возможности" проверьте, включен ли в BackgroundModes Location Updates. Если он включен, попробуйте проверить, содержит ли ваш текущий менеджер местоположений регион, который вы указали, проверив NSLog(@"Monitored Regions %@",self.locationManager.monitoredRegions);

Затем, если пользовательское устройство находится в текущем местоположении (широта и долгота), делегаты didEnterRegion: и didExitRegion: не будут запускаться. Используйте didDetermineState: метод, чтобы определить, находится ли пользователь / устройство в текущем регионе, который отслеживается. Если это так, didDetermineState: будет запущен. Как только пользователь покидает регион, будет активирован didExitRegion:

Затем, после того, как также, если делегаты не являются триггерными, тогда найдите затем ошибку, используя следующее в делегате - (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error { NSLog(@"Failed to Monitor %@", error); }

Другие вопросы по тегам