Мониторинг региона 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);
}