iOS区域监控不工作



我已经做了几个月的iOS开发,最近我正在开发一个公交应用。我目前正在模仿公共汽车的运动,并在公共汽车站设置多个注释。出于测试目的,我只设置了一个公共汽车站,并试图监视公共汽车何时进入该区域并退出。

奇怪的是,我的didStartMonitoringForRegion方法被完美地调用了,但didEnterRegiondidExitRegion方法都没有被调用。每次我运行这个程序,公共汽车几乎都没有提示我过站。

有人能解释一下为什么会发生这种情况以及如何解决它吗?

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

我最终使用了CLRegion.containsCoordinate(location.coordinate)方法。它的工作原理基本相同。

一旦对象进入我设置的区域,它返回true,从这里我可以知道它何时进入和退出该区域

请确保[CLLocationManager regionMonitoringAvailable]返回YESCLLocationManager.monitoredRegions包含有效区域。

同样,来自Apple文档:

在iOS 6中,半径在1到400米之间的区域效果更好在iPhone 4S或更新的设备上。(在ios5中,区域有一个半径1到150米在iPhone 4S和以后的设备上效果更好。)在这些设备上,应用程序可以期望接收到适当的区域3 ~ 5分钟内通知进入或区域退出一般,如果不是更快的话。

应用程序可以在设备移动500米时收到通知或者从之前的通知中获得更多。它不应该期望通知频率超过每五分钟一次。如果设备能够从网络中检索数据,位置管理器更有可能及时地发送通知。

委派未触发的原因有很多。首先转到目标设置,在capabilities选项卡中检查BackgroundModes Location Updates是否启用。如果开启,则尝试检查当前位置管理器是否包含您通过检查指定的区域NSLog(@"Monitored Regions %@",self.locationManager.monitoredRegions);

那么如果用户设备在当前位置(纬度和经度),didEnterRegion:和didExitRegion:委托将不会被触发。使用didDetermineState:方法来查找用户/设备是否处于被监控的当前区域。如果是,didDetermineState:将被触发。一旦用户离开区域,didExitRegion:将被触发。

然后在also之后,如果委托没有触发,那么在委托中使用以下命令查找错误- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error { NSLog(@"Failed to Monitor %@", error); }

相关内容

  • 没有找到相关文章

最新更新