如何设置自定义距离滤镜,在Swift中可以吗?

cri*_*ika 3 mapkit ios swift

我是新手Swift,我尝试了这个

使用MKMapView时如何设置精度和距离过滤器

不知道为什么此代码不起作用:

//start  mehtod out of scope
lazy var locationManager: CLLocationManager! = {
    let locationManager = CLLocationManager()


    //configeration for  user location access
    //The delegate object to receive update events.
    locationManager.delegate = self
    //The receiver does its best to achieve the requested accuracy
    //locationManager.desiredAccuracy = kCLLocationAccuracyBest
     self.locationManager.distanceFilter = 10.0
    //Requests permission to use location services while the app is in the foreground
    locationManager.requestWhenInUseAuthorization()
    //allow update notification when apps stay on background
    locationManager.allowsBackgroundLocationUpdates = true

    return locationManager
}() 
Run Code Online (Sandbox Code Playgroud)

当我设置时它工作正常:

locationManager.desiredAccuracy = kCLLocationAccuracyBest
Run Code Online (Sandbox Code Playgroud)

所以我想要什么:

如果用户更改其位置然后连续15分钟调用一个方法,我希望每250米获得一次LAT和LONG

 pushLocation(lat:double,long:double)
Run Code Online (Sandbox Code Playgroud)

Ron*_*iel 5

这是我正在使用的代码-全部在Swift 3.0中。

locationManager的此设置将照顾您要进行的距离过滤和精度:

lazy var locationManager: CLLocationManager = {
    [unowned self] in
    var _locationManager = CLLocationManager()
    _locationManager.delegate = self
    _locationManager.desiredAccuracy = [Your Value For trackingAccuracy - see below]
    _locationManager.distanceFilter = [Your Value For the filter i.e., 250 for 250 meters]
    _locationManager.allowsBackgroundLocationUpdates = true
    _locationManager.pausesLocationUpdatesAutomatically = false 
    _locationManager.activityType = .fitness
    return _locationManager
    }()
Run Code Online (Sandbox Code Playgroud)

精度设置将来自位置管理器中的预定义设置,例如kCLLocationAccuracyNearestTenMeters或kCLLocationAccuracyHundredMeters。

即使您的应用程序不在前台,允许后台更新的选项也可以让您获得新的积分。如果手机会不时停止移动,则有必要自动关闭暂停功能-否则,如果您的用户停止休息5分钟并且不会重新打开电源,它将自动关闭捕获功能-您必须在重置手机时重置这些功能重做。

授权状态应通过以下单独检查进行处理,以便您可以请求授权(如果尚未提供):

    if CLLocationManager.authorizationStatus() != .authorizedAlways     // Check authorization for location tracking
    {
        locationManager.requestAlwaysAuthorization()                    // Will callbackdidChange... once user responds
    } else {
        locationManager.startUpdatingLocation()
    }
Run Code Online (Sandbox Code Playgroud)

由于获得授权存在延迟,因此如果必须发出请求,则需要等待请求它开始更新位置,直到您从locationManager收到回复为止,可以执行以下操作:

@nonobjc func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    switch status
    {
    case .authorizedAlways:
        locationManager.startUpdatingLocation()

    default:
        [Whatever you want to do - you can't get locations]
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要.authorizedAlways,根据您的用例,您也许可以摆脱.authorizedWhenInUse的束缚。

我会根据locationManager传回给我的位置中的准确性字段添加一个额外的准确性过滤器。注意,有单独的水平和垂直精度值(以米为单位的置信距离);如果要使用高程值,则需要注意第二个精度值,因为在iPhone中,高程固有地精度较低。

我还要检查是否在上一个点之后捕获了新点-有时会出现乱序值,并指示“问题”值。我读过您可能会获得小于0的精度值来指示问题,因此尽管我没有看到此问题,但您可能需要在使用位置之前进行检查。这是代码:

// Called back by location manager - passes arrays of new CLLocation points captured. With distanceFilter set to 250, this will get called for a change of 250M.  You'll want to save the value for your timed pushLocation function.

// This function needs to be trim as it continues to be called when TrailHead is in the background and, if 
// we take too long we'll get killed by iOS.

var savePosition: CLLocationCoordinate2D?
private var latestTimeProcessed = Date()  // Initialize to ensure any point accepted received after initialization

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
    for location in locations {
        if latestTimeProcessed.compare(location.timeStamp) == .orderedAscending        // Out of seq indicates a locationManager problem - discard
            && location.horizontalAccuracy < [Whatever accuracy limit you want to use]    // Applying a user-selected quality filter
        {
            latestTimeProcessed = location.timeStamp      // Used to discard any earlier timestamped points returned by the location manager
            [PROCESS THE POSITION HERE - E.G.]

            savePosition = locations.last

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

至于推送更新,我要添加一个计时器

private var myTimer: Timer? = nil  
private var longInterval = 900.0     // 900 seconds = 15 minutes

override func viewDidLoad()
{
    ....
        myTimer = Timer(timeInterval: timerInterval, target: myself, selector: #selector(myself.pushLocation), userInfo: nil, repeats: true)
        RunLoop.current.add(myTimer!, forMode: RunLoopMode.commonModes)
    ....
}

pushLocation(lat:double,long:double){
    [Use savePosition.latitude, savePosition.longitude]
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助...