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

Sjo*_*ors 20 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>
Run Code Online (Sandbox Code Playgroud)

如果我在地图上打印这些位置(geoplaner.com是我的朋友),我会看到:

积分印在地图上

备注:点BDFH位于同一位置,但为了解决问题,我将这些点放在彼此相邻的一行上.

正如您所看到的,如果您按照序列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];
Run Code Online (Sandbox Code Playgroud)

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

[_manager startUpdatingLocation];
Run Code Online (Sandbox Code Playgroud)

使用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]];
}
Run Code Online (Sandbox Code Playgroud)

感觉就像位置管理器中的iOS9错误,它给了我关于用户下落的错误结果.如果我搜索Stackoverflow.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>
Run Code Online (Sandbox Code Playgroud)

在地图上:

第二个例子

注意: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公里/小时)的速度行驶.

第3点意味着我无法通过保持最后一个GPS日期来修复它并跳过最后一个之前的所有内容.

- >例3:

总GPX文件: 总GPX文件

放大了问题所在: 放大了问题

将双重和错误的订单点移到彼此旁边: 将双重和错误的订单点移到彼此旁边

只需重新加载对ABCD符号感兴趣的点数. 只需重新加载对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>
Run Code Online (Sandbox Code Playgroud)

在此文件中,问题发生了几次,但似乎位于2个问题位置.之后没有问题,但用户在一些KM之后杀死了应用程序.

--> I've tried:

  1. Setting ActivityType to CLActivityTypeAutomotiveNavigation
  2. Setting pauseLocationUpdatesAuto to YES
  3. DesiredAccuracy to kCLLocationAccuracyBestForNavigation
  4. Moving everything to the main thread and don't do any thread changing.
  5. Extending the logging to see if my array Locations contains more then one locationobject, but this isn't the case.
  6. Logging the HASH and Pointer location, but they are all differently.

--> I've learned:

  1. Don't set pausesLocationUpdatesAutomatically to FALSE. It's default TRUE and for a navigation app it should stay TRUE. You will get a lot more locations when you set this to FALSE, locations that are no different to another one.
  2. 在CLLocationManager上设置一次属性,当您将属性更改为通常很奇怪时,更多位置将到达委托.例如:如果在委托方法didUpdateLocation中设置这些属性,则最终会在完全相同的毫秒上找到4个位置.

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

Sjo*_*ors 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).它默认为启用,对于导航应用程序,它应保持启用状态.禁用此功能后,您将获得更多位置,这些位置与另一个位置没有区别.

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