iOS9 中的 CLLocationManager 给出了错误的位置(iOS8 没问题)
CLLocationManager in iOS9 giving incorrect locations (iOS8 is OK)
从 iOS9 开始,我们在 CCLocationManager 的位置上遇到了一些奇怪的问题。 iOS7-8没有问题。奇怪的位置会导致应用程序出错。该应用程序是在开车时使用的,我们在 TestFlight 中有大约 50 名测试用户,其中一些人报告了这些问题。
该应用对位置更新做出反应,每次位置更新,每 25 米和每 50 米都有事情要做。为了测试,我将所有这些位置存储在一个数组中。我们的测试用户有一个按钮,可以通过邮件将 GPX 格式的历史记录发送给我。
例如以下12个地址发给我:
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="flitsmeister-ios-app-test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<wpt lat="51.28165091" lon="5.77329012">
<datetimegps>2015-09-29T04:36:55.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:55.460</datetimeprocessed>
<course>61.5</course>
<speed>13.3</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.1</altitude>
<sequencenr>0</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:55.506</datetimegps>
<datetimeprocessed>2015-09-29T04:36:55.523</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>1</sequencenr>
</wpt>
<wpt lat="51.28171319" lon="5.77345935">
<datetimegps>2015-09-29T04:36:56.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:56.441</datetimeprocessed>
<course>61.2</course>
<speed>13.2</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.0</altitude>
<sequencenr>2</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:56.562</datetimegps>
<datetimeprocessed>2015-09-29T04:36:56.571</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>3</sequencenr>
</wpt>
<wpt lat="51.28177064" lon="5.77362548">
<datetimegps>2015-09-29T04:36:57.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:57.440</datetimeprocessed>
<course>60.1</course>
<speed>13.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>32.9</altitude>
<sequencenr>4</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:57.541</datetimegps>
<datetimeprocessed>2015-09-29T04:36:57.558</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>5</sequencenr>
</wpt>
<wpt lat="51.28182383" lon="5.77380183">
<datetimegps>2015-09-29T04:36:58.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:58.438</datetimeprocessed>
<course>61.2</course>
<speed>13.7</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.3</altitude>
<sequencenr>6</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:58.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:58.491</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>7</sequencenr>
</wpt>
<wpt lat="51.28188803" lon="5.77398322">
<datetimegps>2015-09-29T04:36:59.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:59.431</datetimeprocessed>
<course>61.5</course>
<speed>14.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.4</altitude>
<sequencenr>8</sequencenr>
</wpt>
<wpt lat="51.28202386" lon="5.77435235">
<datetimegps>2015-09-29T04:37:01.371</datetimegps>
<datetimeprocessed>2015-09-29T04:37:01.432</datetimeprocessed>
<course>61.2</course>
<speed>14.9</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.5</altitude>
<sequencenr>9</sequencenr>
</wpt>
<wpt lat="51.28188803" lon="5.77398322">
<datetimegps>2015-09-29T04:37:01.444</datetimegps>
<datetimeprocessed>2015-09-29T04:37:01.454</datetimeprocessed>
<course>61.5</course>
<speed>14.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.4</altitude>
<sequencenr>10</sequencenr>
</wpt>
<wpt lat="51.28208027" lon="5.77454128">
<datetimegps>2015-09-29T04:37:02.371</datetimegps>
<datetimeprocessed>2015-09-29T04:37:02.430</datetimeprocessed>
<course>61.9</course>
<speed>15.1</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.3</altitude>
<sequencenr>11</sequencenr>
</wpt>
<wpt lat="51.28188803" lon="5.77398322">
<datetimegps>2015-09-29T04:37:02.513</datetimegps>
<datetimeprocessed>2015-09-29T04:37:02.521</datetimeprocessed>
<course>61.5</course>
<speed>14.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.4</altitude>
<sequencenr>12</sequencenr>
</wpt>
<wpt lat="51.28217918" lon="5.77472677">
<datetimegps>2015-09-29T04:37:03.371</datetimegps>
<datetimeprocessed>2015-09-29T04:37:03.434</datetimeprocessed>
<course>61.5</course>
<speed>15.2</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.5</altitude>
<sequencenr>13</sequencenr>
</wpt>
</gpx>
如果我在地图上打印这些位置(geoplaner.com 是我的朋友),我会看到:
备注:点 B D F H 在同一位置,但为了说明问题,我将它们放在 1 行并排。
如您所见,如果您遵循 A、B、C 的顺序,您会发现 B 点不在正确的位置。
从iOS9版本开始,几乎每个测试用户都在一周内经历过一两次这种情况。
下面是我们使用的一些代码:
CLLocationManager(在平均线程上):
_manager = [[CLLocationManager alloc] init];
_manager.delegate = self;
_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_manager.activityType = CLActivityTypeAutomotiveNavigation;
_manager.pausesLocationUpdatesAutomatically = TRUE;
if([_manager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
_manager.allowsBackgroundLocationUpdates = TRUE;
[_manager requestAlwaysAuthorization];
在另一种方法中,我调用启动(也是在应用程序启动时调用,并在应用程序终止时调用它)。 (主线程)
[_manager startUpdatingLocation];
使用位置的代码(我删除了一些代码以保持示例清晰):
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *lastLocation = [locations lastObject];
// test that the horizontal accuracy does not indicate an invalid measurement
if (lastLocation.horizontalAccuracy < 0)
return;
// test the age of the location measurement to determine if the measurement is cached
// in most cases you will not want to rely on cached measurements
NSTimeInterval locationAge = -[lastLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0)
return;
NSDate *dateLocationArrived = [NSDate date];
CLLocation *beforeLocationRealtime = [self.LastLocationRealtime copy];
CLLocation *newLocation = [lastLocation copy];
//Realtime location.
[self setSpeedForLocation:[newLocation copy] withOldRealtimeLocation:[beforeLocationRealtime copy]];
[_delegateKaart updatedRealtimeLocation:newLocation fromPreviousLocation:[self.PreviousCurrentLocation copy]];
self.BeforeLastLocationRealtime = [self.LastLocationRealtime copy];
self.LastLocationRealtime = [newLocation copy];
if([self.CurrentLocation distanceFromLocation:newLocation] < 50) //Less then 50m?
{
if([_locationEach25m distanceFromLocation:newLocation] > 25)
{
//Nieuwe last 25m.
_locationEach25m = [newLocation copy];
//Each 25m do
[_delegateDashboard updatedLocation:[newLocation copy]];
[_delegateSignalering locationUpdated:[newLocation copy]];
[self holdLast200LocationsAndAddLocation:[lastLocation copy] withLocationArray:locations AndArriveDate:dateLocationArrived AndVerwerkt:TRUE];
}
else
[self holdLast200LocationsAndAddLocation:[lastLocation copy] withLocationArray:locations AndArriveDate:dateLocationArrived AndVerwerkt:FALSE];
return;//Stop
}
//Each 50m
[self holdLast200LocationsAndAddLocation:[lastLocation copy] withLocationArray:locations AndArriveDate:dateLocationArrived AndVerwerkt:TRUE];
_locationEach25m = [newLocation copy]; //Also new last 25m .
self.PreviousCurrentLocation = [self.CurrentLocation copy];//50m back.
self.CurrentLocation = [newLocation copy];
[_delegateDashboard updatedLocation:[newLocation copy]];
[_delegateSignalering locationUpdated:[newLocation copy]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_delegateCountryDetector locationUpdated:[newLocation copy]];
[self setHuidigeWegForLocation:[newLocation copy]];
});
[[SignaleringController sharedInstance] runSignaleringCheckForLocation:[newLocation copy]];
}
感觉像是 locationmanager 中的一个 iOS9 错误,它给我关于用户行踪的错误结果。如果我搜索 whosebug.com 似乎只有我一个。
--> 例子 2:
<wpt lat="52.32835728" lon="5.05861943">
<datetimegps>2015-10-01T06:27:29.905</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:30.196</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:30.205</datetimeprocessed>
<c>138.4</c>
<s>26.5</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>6.0</accuracyvertical>
<al>5.9</al>
<nr>95</nr>
</wpt>
<wpt lat="52.32813366" lon="5.05927501">
<datetimegps>2015-10-01T06:27:31.905</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:32.275</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:32.301</datetimeprocessed>
<c>119.5</c>
<s>26.0</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>4.0</accuracyvertical>
<al>5.7</al>
<nr>96</nr>
</wpt>
<wpt lat="52.32835728" lon="5.05861943">
<datetimegps>2015-10-01T06:27:33.196</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:33.203</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:33.275</datetimeprocessed>
<c>138.4</c>
<s>26.5</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>6.0</accuracyvertical>
<al>5.9</al>
<nr>97</nr>
</wpt>
<wpt lat="52.32802075" lon="5.05960610">
<datetimegps>2015-10-01T06:27:32.905</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:33.246</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:33.283</datetimeprocessed>
<c>119.2</c>
<s>26.3</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>4.0</accuracyvertical>
<al>5.3</al>
<nr>98</nr>
</wpt>
在地图上:
注意:A和C在准确的位置,我手动更改它们以显示A在C后面。
以下内容很奇怪:
- 4rd/D 的 GPS 时间早于 3rd/C
- 不知何故,我没有找到 06:27:31 的位置,但得到了两个 06:27:33
- 1st/A 和 3rd/C 具有相同的 GPS 坐标。这不可能是正确的,因为汽车以 26m/s (93km/h) 的速度行驶在高速公路上。
第 3 点意味着我无法通过保持最后一个 GPS 日期并跳过比最后一个更早的所有内容来修复它。
--> 例子3:
GPX 文件总数:
放大问题:
将重复的和错误的订单点并排移动:
刚刚用 ABCD 符号重新加载了我感兴趣的点。
上面截图中的GPX文件:
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="flitsmeister-ios-app-test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<wpt lat="51.89792674" lon="4.54830456">
<tgps>2015-09-29T15:23:40.999</tgps>
<tv>2015-09-29T15:23:53.850</tv>
<c>131.8</c>
<s>13.1</s>
<ah>5.0</ah>
<av>3.0</av>
<al>2.0</al>
<nr>464</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.910</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>465</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.929</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>466</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.932</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>467</nr>
</wpt>
<wpt lat="51.89762654" lon="4.54890185">
<tgps>2015-09-29T15:23:44.999</tgps>
<tv>2015-09-29T15:23:53.933</tv>
<c>128.0</c>
<s>13.4</s>
<ah>5.0</ah>
<av>4.0</av>
<al>0.6</al>
<nr>468</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.965</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>469</nr>
</wpt>
<wpt lat="51.89755810" lon="4.54904694">
<tgps>2015-09-29T15:23:45.999</tgps>
<tv>2015-09-29T15:24:02.016</tv>
<c>126.9</c>
<s>12.5</s>
<ah>5.0</ah>
<av>4.0</av>
<al>0.2</al>
<nr>470</nr>
</wpt>
<wpt lat="51.89800163" lon="4.54815385">
<tgps>2015-09-29T15:23:47.731</tgps>
<tv>2015-09-29T15:24:02.068</tv>
<c>132.9</c>
<s>12.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>2.3</al>
<nr>471</nr>
</wpt>
<wpt lat="51.89800163" lon="4.54815385">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:24:05.832</tv>
<c>132.9</c>
<s>12.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>2.3</al>
<nr>472</nr>
</wpt>
<wpt lat="51.89749909" lon="4.54917803">
<tgps>2015-09-29T15:23:46.999</tgps>
<tv>2015-09-29T15:24:05.842</tv>
<c>126.9</c>
<s>10.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>8.4</al>
<nr>473</nr>
</wpt>
<wpt lat="51.89800163" lon="4.54815385">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:24:06.289</tv>
<c>132.9</c>
<s>12.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>2.3</al>
<nr>474</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:24:06.307</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>475</nr>
</wpt>
<wpt lat="51.89732735" lon="4.54958171">
<tgps>2015-09-29T15:23:52.999</tgps>
<tv>2015-09-29T15:24:06.339</tv>
<c>121.6</c>
<s>2.9</s>
<ah>5.0</ah>
<av>4.0</av>
<al>-2.3</al>
<nr>476</nr>
</wpt>
</gpx>
在此文件中,问题发生了几次,但似乎位于 2 个问题位置。之后就没有问题了,但是用户在一些 KM 后关闭了应用程序。
--> 我试过了:
- 将 ActivityType 设置为 CLActivityTypeAutomotiveNavigation
- 将 pauseLocationUpdatesAuto 设置为 YES
- DesiredAccuracy 到 kCLLocationAccuracyBestForNavigation
- 将所有内容移至主线程,不进行任何线程更改。
- 扩展日志记录以查看我的位置数组是否包含一个以上的位置对象,但事实并非如此。
- 记录 HASH 和指针位置,但它们都不同。
--> 我了解到:
不要将 pausesLocationUpdatesAutomatically 设置为 FALSE。它默认为 TRUE,对于导航应用程序,它应该保持 TRUE。当您将此设置为 FALSE 时,您将获得更多位置,这些位置与另一个位置没有什么不同。
在 CLLocationManager 上设置一次属性,当您将属性更改为通常很奇怪并且更多位置将到达委托时。例如:如果您在委托方法 didUpdateLocation 中设置这些属性,您将在完全相同的毫秒内得到 4 个位置。
_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_manager.activityType = CLActivityTypeAutomotiveNavigation;
我不确定这就是整个故事,但在调查了 2 天后,我认为这是正在发生的事情。
如果 locationManager 在任何时候被重新创建,它将执行您正在描述的操作(重复位置)。这在某种程度上是有道理的,如果您创建一个新的 locationManager 或重新初始化您当前的位置管理器,它将接收另一组您当前的位置。我能够通过创建一个玩具应用程序来获得类似的结果,该应用程序在每次按下按钮并定期单击按钮时重新创建 locationManager。
如果 locationManager 失去网络连接(手机信号和 wifi),则无法传输位置数据。简而言之,我相信 locationManager 会在设备失去互联网连接时被销毁,并且在稍后重新创建时它会使用旧坐标。为什么要缓存这些值以及时间签名如何不正确对我来说仍然是个谜。
最后,我创建了一个 toy app,它使用与您用来初始化它的 locationManager 相同的代码(减去用于存储前 200 个位置的代码)。它所做的只是在每次收到您的位置时在地图上放置一个图钉。我带着它四处转转,确实看到了不一致的位置,但与你描述的不完全一样。我确实看到了奇怪的行为,这一事实使我认为这是 iOS 9 而不是您的代码的错误。
在这一点上,考虑到目前在 iOS 9 中发现的所有其他错误,我认为将此问题归咎于 Apple 是公平的。
我终于想通了。以下是错误的地方:
我的项目中有另一个 CLLocationManager 运行 每秒这段代码:
[locationManager startUpdatingLocation];
if([locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) {
locationManager.allowsBackgroundLocationUpdates = 真;
}
我不止一次在 CLLocationManager 上设置属性。当您过于频繁地更改属性时,奇怪的和额外的位置将到达委托。例如:如果您在委托方法中设置这些属性 didUpdateLocation
您将在完全相同的毫秒内得到 4 个位置。
_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_manager.activityType = CLActivityTypeAutomotiveNavigation;
我们发现一位测试用户的 GPS 芯片坏了或什么的。出于某种原因,他的设备偶尔会报告错误的 GPS 坐标。确保至少有两个用户报告错误!在某些时候,当我们修复点 1 和点 2 时,该用户出现此错误,但所有其他用户都正常。后来他还报告了商店版本的错误(使用 iOS8 构建)。
不要禁用 pausesLocationUpdatesAutomatically
(将其设置为 false)。它默认为启用,对于导航应用程序,它应该保持启用状态。禁用此功能后,您将获得更多位置,这些位置与其他位置没有什么不同。
所以是的,iOS8 和 iOS9 之间有很大的区别。如果您遇到奇怪的位置,请检查上面的这些要点。
无法添加评论..
仍然只能通过设置 distanceFilter 才能正常工作
我按照你的回答:
_locationManager.activityType = CLActivityTypeFitness;
_locationManager.pausesLocationUpdatesAutomatically = YES;
还可以找到一些这样的有线位置:
第一个完全等于第三个,
这是为什么...
从 iOS9 开始,我们在 CCLocationManager 的位置上遇到了一些奇怪的问题。 iOS7-8没有问题。奇怪的位置会导致应用程序出错。该应用程序是在开车时使用的,我们在 TestFlight 中有大约 50 名测试用户,其中一些人报告了这些问题。
该应用对位置更新做出反应,每次位置更新,每 25 米和每 50 米都有事情要做。为了测试,我将所有这些位置存储在一个数组中。我们的测试用户有一个按钮,可以通过邮件将 GPX 格式的历史记录发送给我。
例如以下12个地址发给我:
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="flitsmeister-ios-app-test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<wpt lat="51.28165091" lon="5.77329012">
<datetimegps>2015-09-29T04:36:55.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:55.460</datetimeprocessed>
<course>61.5</course>
<speed>13.3</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.1</altitude>
<sequencenr>0</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:55.506</datetimegps>
<datetimeprocessed>2015-09-29T04:36:55.523</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>1</sequencenr>
</wpt>
<wpt lat="51.28171319" lon="5.77345935">
<datetimegps>2015-09-29T04:36:56.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:56.441</datetimeprocessed>
<course>61.2</course>
<speed>13.2</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.0</altitude>
<sequencenr>2</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:56.562</datetimegps>
<datetimeprocessed>2015-09-29T04:36:56.571</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>3</sequencenr>
</wpt>
<wpt lat="51.28177064" lon="5.77362548">
<datetimegps>2015-09-29T04:36:57.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:57.440</datetimeprocessed>
<course>60.1</course>
<speed>13.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>32.9</altitude>
<sequencenr>4</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:57.541</datetimegps>
<datetimeprocessed>2015-09-29T04:36:57.558</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>5</sequencenr>
</wpt>
<wpt lat="51.28182383" lon="5.77380183">
<datetimegps>2015-09-29T04:36:58.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:58.438</datetimeprocessed>
<course>61.2</course>
<speed>13.7</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.3</altitude>
<sequencenr>6</sequencenr>
</wpt>
<wpt lat="51.28138654" lon="5.77244497">
<datetimegps>2015-09-29T04:36:58.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:58.491</datetimeprocessed>
<course>69.3</course>
<speed>13.5</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.7</altitude>
<sequencenr>7</sequencenr>
</wpt>
<wpt lat="51.28188803" lon="5.77398322">
<datetimegps>2015-09-29T04:36:59.371</datetimegps>
<datetimeprocessed>2015-09-29T04:36:59.431</datetimeprocessed>
<course>61.5</course>
<speed>14.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.4</altitude>
<sequencenr>8</sequencenr>
</wpt>
<wpt lat="51.28202386" lon="5.77435235">
<datetimegps>2015-09-29T04:37:01.371</datetimegps>
<datetimeprocessed>2015-09-29T04:37:01.432</datetimeprocessed>
<course>61.2</course>
<speed>14.9</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.5</altitude>
<sequencenr>9</sequencenr>
</wpt>
<wpt lat="51.28188803" lon="5.77398322">
<datetimegps>2015-09-29T04:37:01.444</datetimegps>
<datetimeprocessed>2015-09-29T04:37:01.454</datetimeprocessed>
<course>61.5</course>
<speed>14.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.4</altitude>
<sequencenr>10</sequencenr>
</wpt>
<wpt lat="51.28208027" lon="5.77454128">
<datetimegps>2015-09-29T04:37:02.371</datetimegps>
<datetimeprocessed>2015-09-29T04:37:02.430</datetimeprocessed>
<course>61.9</course>
<speed>15.1</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.3</altitude>
<sequencenr>11</sequencenr>
</wpt>
<wpt lat="51.28188803" lon="5.77398322">
<datetimegps>2015-09-29T04:37:02.513</datetimegps>
<datetimeprocessed>2015-09-29T04:37:02.521</datetimeprocessed>
<course>61.5</course>
<speed>14.4</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.4</altitude>
<sequencenr>12</sequencenr>
</wpt>
<wpt lat="51.28217918" lon="5.77472677">
<datetimegps>2015-09-29T04:37:03.371</datetimegps>
<datetimeprocessed>2015-09-29T04:37:03.434</datetimeprocessed>
<course>61.5</course>
<speed>15.2</speed>
<accuracyhorizontal>5.0</accuracyhorizontal>
<accuracyvertical>3.0</accuracyvertical>
<altitude>33.5</altitude>
<sequencenr>13</sequencenr>
</wpt>
</gpx>
如果我在地图上打印这些位置(geoplaner.com 是我的朋友),我会看到:
备注:点 B D F H 在同一位置,但为了说明问题,我将它们放在 1 行并排。
如您所见,如果您遵循 A、B、C 的顺序,您会发现 B 点不在正确的位置。
从iOS9版本开始,几乎每个测试用户都在一周内经历过一两次这种情况。
下面是我们使用的一些代码:
CLLocationManager(在平均线程上):
_manager = [[CLLocationManager alloc] init];
_manager.delegate = self;
_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_manager.activityType = CLActivityTypeAutomotiveNavigation;
_manager.pausesLocationUpdatesAutomatically = TRUE;
if([_manager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
_manager.allowsBackgroundLocationUpdates = TRUE;
[_manager requestAlwaysAuthorization];
在另一种方法中,我调用启动(也是在应用程序启动时调用,并在应用程序终止时调用它)。 (主线程)
[_manager startUpdatingLocation];
使用位置的代码(我删除了一些代码以保持示例清晰):
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *lastLocation = [locations lastObject];
// test that the horizontal accuracy does not indicate an invalid measurement
if (lastLocation.horizontalAccuracy < 0)
return;
// test the age of the location measurement to determine if the measurement is cached
// in most cases you will not want to rely on cached measurements
NSTimeInterval locationAge = -[lastLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0)
return;
NSDate *dateLocationArrived = [NSDate date];
CLLocation *beforeLocationRealtime = [self.LastLocationRealtime copy];
CLLocation *newLocation = [lastLocation copy];
//Realtime location.
[self setSpeedForLocation:[newLocation copy] withOldRealtimeLocation:[beforeLocationRealtime copy]];
[_delegateKaart updatedRealtimeLocation:newLocation fromPreviousLocation:[self.PreviousCurrentLocation copy]];
self.BeforeLastLocationRealtime = [self.LastLocationRealtime copy];
self.LastLocationRealtime = [newLocation copy];
if([self.CurrentLocation distanceFromLocation:newLocation] < 50) //Less then 50m?
{
if([_locationEach25m distanceFromLocation:newLocation] > 25)
{
//Nieuwe last 25m.
_locationEach25m = [newLocation copy];
//Each 25m do
[_delegateDashboard updatedLocation:[newLocation copy]];
[_delegateSignalering locationUpdated:[newLocation copy]];
[self holdLast200LocationsAndAddLocation:[lastLocation copy] withLocationArray:locations AndArriveDate:dateLocationArrived AndVerwerkt:TRUE];
}
else
[self holdLast200LocationsAndAddLocation:[lastLocation copy] withLocationArray:locations AndArriveDate:dateLocationArrived AndVerwerkt:FALSE];
return;//Stop
}
//Each 50m
[self holdLast200LocationsAndAddLocation:[lastLocation copy] withLocationArray:locations AndArriveDate:dateLocationArrived AndVerwerkt:TRUE];
_locationEach25m = [newLocation copy]; //Also new last 25m .
self.PreviousCurrentLocation = [self.CurrentLocation copy];//50m back.
self.CurrentLocation = [newLocation copy];
[_delegateDashboard updatedLocation:[newLocation copy]];
[_delegateSignalering locationUpdated:[newLocation copy]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_delegateCountryDetector locationUpdated:[newLocation copy]];
[self setHuidigeWegForLocation:[newLocation copy]];
});
[[SignaleringController sharedInstance] runSignaleringCheckForLocation:[newLocation copy]];
}
感觉像是 locationmanager 中的一个 iOS9 错误,它给我关于用户行踪的错误结果。如果我搜索 whosebug.com 似乎只有我一个。
--> 例子 2:
<wpt lat="52.32835728" lon="5.05861943">
<datetimegps>2015-10-01T06:27:29.905</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:30.196</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:30.205</datetimeprocessed>
<c>138.4</c>
<s>26.5</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>6.0</accuracyvertical>
<al>5.9</al>
<nr>95</nr>
</wpt>
<wpt lat="52.32813366" lon="5.05927501">
<datetimegps>2015-10-01T06:27:31.905</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:32.275</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:32.301</datetimeprocessed>
<c>119.5</c>
<s>26.0</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>4.0</accuracyvertical>
<al>5.7</al>
<nr>96</nr>
</wpt>
<wpt lat="52.32835728" lon="5.05861943">
<datetimegps>2015-10-01T06:27:33.196</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:33.203</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:33.275</datetimeprocessed>
<c>138.4</c>
<s>26.5</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>6.0</accuracyvertical>
<al>5.9</al>
<nr>97</nr>
</wpt>
<wpt lat="52.32802075" lon="5.05960610">
<datetimegps>2015-10-01T06:27:32.905</datetimegps>
<datetimearrivedincode>2015-10-01T06:27:33.246</datetimearrivedincode>
<datetimeprocessed>2015-10-01T06:27:33.283</datetimeprocessed>
<c>119.2</c>
<s>26.3</s>
<accuracyhorizontal>10.0</accuracyhorizontal>
<accuracyvertical>4.0</accuracyvertical>
<al>5.3</al>
<nr>98</nr>
</wpt>
在地图上:
注意:A和C在准确的位置,我手动更改它们以显示A在C后面。
以下内容很奇怪:
- 4rd/D 的 GPS 时间早于 3rd/C
- 不知何故,我没有找到 06:27:31 的位置,但得到了两个 06:27:33
- 1st/A 和 3rd/C 具有相同的 GPS 坐标。这不可能是正确的,因为汽车以 26m/s (93km/h) 的速度行驶在高速公路上。
第 3 点意味着我无法通过保持最后一个 GPS 日期并跳过比最后一个更早的所有内容来修复它。
--> 例子3:
GPX 文件总数:
放大问题:
将重复的和错误的订单点并排移动:
刚刚用 ABCD 符号重新加载了我感兴趣的点。
上面截图中的GPX文件:
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="flitsmeister-ios-app-test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<wpt lat="51.89792674" lon="4.54830456">
<tgps>2015-09-29T15:23:40.999</tgps>
<tv>2015-09-29T15:23:53.850</tv>
<c>131.8</c>
<s>13.1</s>
<ah>5.0</ah>
<av>3.0</av>
<al>2.0</al>
<nr>464</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.910</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>465</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.929</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>466</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.932</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>467</nr>
</wpt>
<wpt lat="51.89762654" lon="4.54890185">
<tgps>2015-09-29T15:23:44.999</tgps>
<tv>2015-09-29T15:23:53.933</tv>
<c>128.0</c>
<s>13.4</s>
<ah>5.0</ah>
<av>4.0</av>
<al>0.6</al>
<nr>468</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:23:53.965</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>469</nr>
</wpt>
<wpt lat="51.89755810" lon="4.54904694">
<tgps>2015-09-29T15:23:45.999</tgps>
<tv>2015-09-29T15:24:02.016</tv>
<c>126.9</c>
<s>12.5</s>
<ah>5.0</ah>
<av>4.0</av>
<al>0.2</al>
<nr>470</nr>
</wpt>
<wpt lat="51.89800163" lon="4.54815385">
<tgps>2015-09-29T15:23:47.731</tgps>
<tv>2015-09-29T15:24:02.068</tv>
<c>132.9</c>
<s>12.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>2.3</al>
<nr>471</nr>
</wpt>
<wpt lat="51.89800163" lon="4.54815385">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:24:05.832</tv>
<c>132.9</c>
<s>12.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>2.3</al>
<nr>472</nr>
</wpt>
<wpt lat="51.89749909" lon="4.54917803">
<tgps>2015-09-29T15:23:46.999</tgps>
<tv>2015-09-29T15:24:05.842</tv>
<c>126.9</c>
<s>10.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>8.4</al>
<nr>473</nr>
</wpt>
<wpt lat="51.89800163" lon="4.54815385">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:24:06.289</tv>
<c>132.9</c>
<s>12.8</s>
<ah>5.0</ah>
<av>4.0</av>
<al>2.3</al>
<nr>474</nr>
</wpt>
<wpt lat="51.89745789" lon="4.54927853">
<tgps>2015-09-29T15:23:47.999</tgps>
<tv>2015-09-29T15:24:06.307</tv>
<c>125.9</c>
<s>8.6</s>
<ah>5.0</ah>
<av>6.0</av>
<al>5.4</al>
<nr>475</nr>
</wpt>
<wpt lat="51.89732735" lon="4.54958171">
<tgps>2015-09-29T15:23:52.999</tgps>
<tv>2015-09-29T15:24:06.339</tv>
<c>121.6</c>
<s>2.9</s>
<ah>5.0</ah>
<av>4.0</av>
<al>-2.3</al>
<nr>476</nr>
</wpt>
</gpx>
在此文件中,问题发生了几次,但似乎位于 2 个问题位置。之后就没有问题了,但是用户在一些 KM 后关闭了应用程序。
--> 我试过了:
- 将 ActivityType 设置为 CLActivityTypeAutomotiveNavigation
- 将 pauseLocationUpdatesAuto 设置为 YES
- DesiredAccuracy 到 kCLLocationAccuracyBestForNavigation
- 将所有内容移至主线程,不进行任何线程更改。
- 扩展日志记录以查看我的位置数组是否包含一个以上的位置对象,但事实并非如此。
- 记录 HASH 和指针位置,但它们都不同。
--> 我了解到:
不要将 pausesLocationUpdatesAutomatically 设置为 FALSE。它默认为 TRUE,对于导航应用程序,它应该保持 TRUE。当您将此设置为 FALSE 时,您将获得更多位置,这些位置与另一个位置没有什么不同。
在 CLLocationManager 上设置一次属性,当您将属性更改为通常很奇怪并且更多位置将到达委托时。例如:如果您在委托方法 didUpdateLocation 中设置这些属性,您将在完全相同的毫秒内得到 4 个位置。
_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; _manager.activityType = CLActivityTypeAutomotiveNavigation;
我不确定这就是整个故事,但在调查了 2 天后,我认为这是正在发生的事情。
如果 locationManager 在任何时候被重新创建,它将执行您正在描述的操作(重复位置)。这在某种程度上是有道理的,如果您创建一个新的 locationManager 或重新初始化您当前的位置管理器,它将接收另一组您当前的位置。我能够通过创建一个玩具应用程序来获得类似的结果,该应用程序在每次按下按钮并定期单击按钮时重新创建 locationManager。
如果 locationManager 失去网络连接(手机信号和 wifi),则无法传输位置数据。简而言之,我相信 locationManager 会在设备失去互联网连接时被销毁,并且在稍后重新创建时它会使用旧坐标。为什么要缓存这些值以及时间签名如何不正确对我来说仍然是个谜。
最后,我创建了一个 toy app,它使用与您用来初始化它的 locationManager 相同的代码(减去用于存储前 200 个位置的代码)。它所做的只是在每次收到您的位置时在地图上放置一个图钉。我带着它四处转转,确实看到了不一致的位置,但与你描述的不完全一样。我确实看到了奇怪的行为,这一事实使我认为这是 iOS 9 而不是您的代码的错误。
在这一点上,考虑到目前在 iOS 9 中发现的所有其他错误,我认为将此问题归咎于 Apple 是公平的。
我终于想通了。以下是错误的地方:
我的项目中有另一个 CLLocationManager 运行 每秒这段代码:
[locationManager startUpdatingLocation]; if([locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) { locationManager.allowsBackgroundLocationUpdates = 真; }
我不止一次在 CLLocationManager 上设置属性。当您过于频繁地更改属性时,奇怪的和额外的位置将到达委托。例如:如果您在委托方法中设置这些属性
didUpdateLocation
您将在完全相同的毫秒内得到 4 个位置。_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_manager.activityType = CLActivityTypeAutomotiveNavigation;我们发现一位测试用户的 GPS 芯片坏了或什么的。出于某种原因,他的设备偶尔会报告错误的 GPS 坐标。确保至少有两个用户报告错误!在某些时候,当我们修复点 1 和点 2 时,该用户出现此错误,但所有其他用户都正常。后来他还报告了商店版本的错误(使用 iOS8 构建)。
不要禁用
pausesLocationUpdatesAutomatically
(将其设置为 false)。它默认为启用,对于导航应用程序,它应该保持启用状态。禁用此功能后,您将获得更多位置,这些位置与其他位置没有什么不同。
所以是的,iOS8 和 iOS9 之间有很大的区别。如果您遇到奇怪的位置,请检查上面的这些要点。
无法添加评论..
仍然只能通过设置 distanceFilter 才能正常工作
我按照你的回答:
_locationManager.activityType = CLActivityTypeFitness;
_locationManager.pausesLocationUpdatesAutomatically = YES;
还可以找到一些这样的有线位置:
第一个完全等于第三个, 这是为什么...