Abbiamo riscontrato alcuni problemi strani sulle posizioni da CCLocationManager a partire da iOS9. iOS 7-8 non ha problemi. Le strane posizioni causano errori nell'app. L'app viene utilizzata durante la guida di un'auto e abbiamo circa 50 utenti di test in TestFlight e alcuni di loro stanno segnalando questi problemi.CLLocationManager in iOS9 che fornisce posizioni errate (iOS8 è OK)
L'applicazione reagisce sugli aggiornamenti di posizione, ogni aggiornamento di posizione, ogni 25m e ogni 50 m c'è qualcosa da fare. Per il test ho memorizzato tutte queste posizioni in un array. I nostri utenti di test hanno un pulsante che invierà la cronologia in formato GPX per posta.
Ad esempio, i seguenti 12 luoghi in cui inviano a me:
<?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>
se stampo questi posizione su una mappa (geoplaner.com è il mio amico), vedrò questo:
Nota: i punti BDFH si trovano nella stessa posizione, ma per l'illustrazione del problema ho messo quelli su 1 fila uno accanto all'altro.
Come potete vedere se seguite la sequenza A, B, C vedrete che il punto B non si trova nella posizione giusta.
A partire dalla versione iOS9 quasi ogni utente di test ha riscontrato questa situazione una o due volte in una settimana.
Dopo qualche codice utilizzato:
CLLocationManager (sul filetto media):
_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];
In un altro metodo che chiamano partenza (anche quando inizia dell'app e fermarlo quando termina). (Thread principale)
[_manager startUpdatingLocation];
codice per lavorare con posizioni (ho rimosso il codice per mantenere l'esempio pulito):
- (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]];
}
Ci si sente come un bug di iOS9 nel locationmanager che mi sta dando risultati errati sulla posizione dell'utente. Se cerco Stackoverflow.com sembra Im l'unico.
-> Esempio 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>
Sulla mappa:
Nota: A e C sono sulla posizione esatta, li ho modificato manualmente per mostrare A è dietro C .
Quello che segue è strano:
- 4 °/D ha un tempo di GPS precedente punto poi 3 °/C
- In qualche modo mi hanno dato una posizione per 06:27:31 ma ho due 06:27:33
- 1a/A e 3 °/C hanno la stesse coordinate GPS. Questo non può essere corretto perché l'auto sta guidando l'autostrada a 26m/s (93km/h).
Punto 3 significa che non riesco a correggerlo mantenendo l'ultima data GPS e saltare tutto prima dell'ultimo.
-> Esempio 3:
spostato il doppio dei punti e non corrette di ordine uno accanto all'altro:
Appena ricaricato i punti che mi interessano con le notazioni ABCD.
Il file GPX da quanto sopra screenshot:
<?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>
In questo file il problema si è verificato un paio di volte, ma sembra di individuare in 2 posizioni problematiche. Dopo di che non ci sono più problemi ma l'utente ha ucciso l'app dopo un certo KM.
-> Ho provato:
- Impostazione ActivityType a CLActivityTypeAutomotiveNavigation
- Impostazione pauseLocationUpdatesAuto su YES
- DesiredAccuracy a kCLLocationAccuracyBestForNavigation
- Spostare tutto per il thread principale e non faccio alcuna cambio di filo.
- Estendere la registrazione per vedere se il mio array Locations contiene più di un locationobject, ma questo non è il caso.
- Registrazione della posizione HASH e Pointer, ma sono tutti in modo diverso.
-> ho imparato:
- Non impostare pausesLocationUpdatesAutomatically FALSE. È di default TRUE e per un'app di navigazione dovrebbe rimanere TRUE. Avrai molte più posizioni quando lo imposti su FALSE, posizioni che non sono diverse da un'altra.
Impostare le proprietà su CLLocationManager una volta, quando si modificano le proprietà in modo spesso strano e altre località arriveranno al delegato. Nell'esempio: se si impostano queste proprietà nel metodo delegate, didUpdateLocation si finirà con 4 posizioni sullo stesso millisecondo.
_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; _manager.activityType = CLActivityTypeAutomotiveNavigation;
In qualsiasi punto del codice stai riducendo l'accuratezza? – quant24
Unico punto è quando inizializzo il locationmanager: _manager.desiredAccuracy –
Hai trovato qualche test in cui ciò si verifica per utenti diversi (o test diversi con lo stesso utente) nella stessa area geografica? Forse un tratto di autostrada che ha causato il problema a più utenti? – Aabglov