iOS9中的CLLocationManager给出了错误的位置(iOS8没问题)

时间:2015-09-29 07:46:49

标签: cllocationmanager ios9

从iOS9开始,我们在CCLocationManager的位置上遇到了一些奇怪的问题。 iOS 7-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是我的朋友),我会看到:

Points printed on the map

备注:B D F H点位于同一位置,但为了说明问题,我将这些点放在彼此相邻的一行上。

正如您所看到的,如果您按照序列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];

在另一种方法中,我调用start(也就是当app启动时,并在它终止时停止)。 (主线程)

[_manager startUpdatingLocation];

使用Locations的代码(我删除了一些代码以保持示例清洁):

- (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]];
}

感觉就像位置管理器中的iOS9错误,它给了我关于用户行踪的错误结果。如果我搜索Stackoverflow.com,我似乎是唯一一个。

- &GT;例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>

在地图上:

second example

注意:A和C位于确切位置,我手动更改它们以显示A位于C后面。

以下是奇怪的:

  1. 4rd / D具有较早的GPS时间,然后指向3rd / C
  2. 不知怎的,我没有得到06:27:31的位置但得到了两个06:27:33
  3. 1st / A和3rd / C具有相同的GPS坐标。这是不正确的,因为汽车正在以26米/秒(93公里/小时)的速度行驶。
  4. 第3点意味着我无法通过保持最后一个GPS日期来修复它并跳过最后一个之前的所有内容。

    - &GT;例3:

    总GPX文件: Total GPX file

    解决问题: Zoomed-in at the problem

    将双重和错误的订单点移到彼此旁边: Moved the double and incorrect order points next to each other

    重新加载对ABCD符号感兴趣的点数。 Just reloaded the points im interested in with ABCD notations

    上面屏幕截图中的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之后杀死了应用程序。

    - &GT;我试过了:

    1. 将ActivityType设置为CLActivityTypeAutomotiveNavigation
    2. 将pauseLocationUpdatesAuto设置为YES
    3. DesquireAccuracy to kCLLocationAccuracyBestForNavigation
    4. 将所有内容移至主线程,不要更改任何线程。
    5. 扩展日志记录以查看我的数组Locations是否包含多个locationobject,但事实并非如此。
    6. 记录HASH和指针位置,但它们完全不同。
    7. - &GT;我学会了:

      1. 不要将pausesLocationUpdatesAutomatically设置为FALSE。它默认为TRUE,对于导航应用程序,它应该保持为TRUE。当您将其设置为FALSE时,您将获得更多位置,这些位置与另一个位置没有区别。
      2. 在CLLocationManager上设置一次属性,当您将属性更改为常常很奇怪时,更多位置将到达委托。例如:如果在委托方法didUpdateLocation中设置这些属性,则最终会在完全相同的毫秒上找到4个位置。

        _manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; _manager.activityType = CLActivityTypeAutomotiveNavigation;

3 个答案:

答案 0 :(得分:7)

我终于明白了。以下是错误的事情:

  1. 我的项目中有另一个CLLocationManager,每秒运行一次代码:

    [locationManager startUpdatingLocation]; if([locationManager respondsToSelector:@ selector(allowsBackgroundLocationUpdates)]){     locationManager.allowsBackgroundLocationUpdates = TRUE; }

  2. 我多次在CLLocationManager上设置属性。当您经常更改属性时,奇怪的和额外的位置将到达代表。例如:如果您在委托方法didUpdateLocation中设置这些属性,那么您将在完全相同的毫秒内得到4个位置。

    _manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    _manager.activityType = CLActivityTypeAutomotiveNavigation;

  3. 我们发现一个测试用户的GPS芯片坏了或什么的。由于某种原因,他的设备偶尔会报告错误的GPS坐标。确保至少有两个用户报告错误!在我们修复第1点和第2点的某个时刻,此用户出现此错误,但所有其他用户都没问题。后来他还报告了商店版本的错误(使用iOS8构建)。

  4. 不要禁用pausesLocationUpdatesAutomatically(将其设置为false)。它默认为启用,对于导航应用程序,它应保持启用状态。当您禁用此位置时,您将获得更多位置,这些位置与另一个位置没有区别。

  5. 所以是的,iOS8和iOS9之间存在很大差异。如果您遇到奇怪的位置,请检查以上几点。

答案 1 :(得分:4)

我不确定这是整个故事,但经过2天的调查后,我认为这是正在发生的事情。

如果在任何时候重新创建了locationManager,它将会执行您所描述的内容(重复位置)。这在某种程度上是有道理的,如果您创建一个新的locationManager或重新初始化当前的locationManager,它将收到另一组您当前的位置。通过创建一个玩具应用程序,每次按下按钮并定期单击按钮,我就可以获得类似的结果。

如果locationManager失去网络连接(小区信号和wifi),则无法传输位置数据。简而言之,我相信只要设备丢失了互联网连接,并且在稍后重新创建它时,它就会使用旧坐标来销毁。为什么它缓存这些值以及时间签名如何不正确对我来说仍然是一个谜。

最后,我创建了一个toy app,它使用与初始化它的locationManager相同的代码(减去用于存储前200个位置的代码)。它只是在每次收到您的位置时在地图上放置一个图钉。我带着它开车,确实看到了不一致的位置,但不完全是你所描述的。事实上,我确实看到了奇怪的行为,这让我认为这是iOS 9的错误,而不是你的代码。

此时,考虑到目前为止在iOS 9中发现的所有其他错误,我认为将此问题归功于Apple是公平的。

答案 2 :(得分:0)

无法添加评论..

通过设置distanceFilter

仍然可以正常工作

我按照你的回答: _locationManager.activityType = CLActivityTypeFitness; _locationManager.pausesLocationUpdatesAutomatically = YES;

还可以找到一些这样的有线位置:enter image description here

首先完全等于第三, 为什么......