这是我正在使用的代码 - 全部在 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
}()
精度设置来自位置管理器中的预定义设置,例如 kCLLocationAccuracyNearestTenMeters 或 kCLLocationAccuracyHundredMeters。
即使您的应用不在前台,允许后台更新的选项也能让您获得新积分。如果手机不时停止移动,则需要自动关闭暂停 - 否则,如果您的用户停止休息 5 分钟并且不会重新打开它,它将自动关闭捕获 - 您必须在“重做。
授权状态应单独检查如下,以便您可以在尚未获得授权的情况下请求授权:
if CLLocationManager.authorizationStatus() != .authorizedAlways // Check authorization for location tracking
{
locationManager.requestAlwaysAuthorization() // Will callbackdidChange... once user responds
} else {
locationManager.startUpdatingLocation()
}
由于获得授权存在延迟,如果您必须提出请求,则需要等待请求它开始更新位置,直到您收到 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]
}
}
我需要 .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
}
}
}
就推送更新而言,我会添加一个计时器
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]
}
希望这会有所帮助...