2015-09-13 2 views
1

Я занимаюсь разработкой 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 
    } 
} 

ответ

1

В итоге я использовал метод CLRegion.containsCoordinate(location.coordinate). Он работает почти так же.

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

1

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

Кроме того, от компании Apple документации:

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

И

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

+0

Я очень извиняюсь за довольно поздний ответ. Я пробовал все, что вы предлагали, но все равно не работает. [CLLocationManager regionMonitoringAvailable] устарел и в настоящее время использует CLLocationManager.isMonitoringAvailableForClass(). Он возвращает true, и мои контролируемыеRegions возвращают правильные значения, но все же не обнаружена запись или выход из региона. – eshirima

0

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

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

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

Смежные вопросы