cllocationmanager - usage - startupdatinglocation swift
CLLocationManager en iOS9 que da ubicaciones incorrectas(iOS8 está bien) (3)
Finalmente lo resolví. Las siguientes cosas fueron mal:
Tuve otro CLLocationManager en mi proyecto ejecutando este código cada segundo:
[locationManager startUpdatingLocation]; if ([locationManager respondsToSelector: @selector (allowBackgroundLocationUpdates)]) {locationManager.allowsBackgroundLocationUpdates = TRUE; }
Estuve configurando las propiedades en el CLLocationManager más de una vez. Cuando cambia las propiedades con demasiada frecuencia, las ubicaciones extrañas y extrañas llegarán al delegado. Por ejemplo: si configura estas propiedades en el método delegado
didUpdateLocation
, obtendrá 4 ubicaciones en el mismo milisegundo exacto._manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_manager.activityType = CLActivityTypeAutomotiveNavigation;Hemos descubierto que a un usuario de prueba le rompieron su chip GPS o algo así. Por alguna razón, su dispositivo informó de coordenadas GPS incorrectas de vez en cuando. ¡Asegúrese de que al menos dos usuarios informen un error! En algún momento cuando reparamos los puntos 1 y 2, este usuario tuvo este error, pero todos los demás usuarios estaban bien. Más tarde, también informó de errores con la versión de la tienda (que se construyó con iOS8).
No deshabilite
pausesLocationUpdatesAutomatically
(pausesLocationUpdatesAutomatically
en falso). El valor predeterminado es habilitado y para una aplicación de navegación debería permanecer habilitado. Obtendrá muchas más ubicaciones cuando lo deshabilite, ubicaciones que no son diferentes a otras.
Entonces sí, hay una gran diferencia entre iOS8 y iOS9. Si experimentas lugares extraños, revisa estos puntos arriba.
Experimentamos algunos problemas extraños en las ubicaciones de CCLocationManager a partir de iOS9. iOS 7-8 no tiene problemas. Las ubicaciones extrañas causan errores en la aplicación. La aplicación se usa mientras se conduce un automóvil y tenemos alrededor de 50 usuarios de prueba en TestFlight y algunos de ellos informan sobre estos problemas.
La aplicación reacciona ante las actualizaciones de ubicación, cada actualización de ubicación, cada 25m y cada 50m hay algo que hacer. Para la prueba he almacenado todas estas ubicaciones en una matriz. Nuestros usuarios de prueba tienen un botón que me enviará el historial en formato GPX por correo.
Por ejemplo las siguientes 12 ubicaciones donde me envían:
<?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>
Si imprimo esta ubicación en un mapa (geoplaner.com es mi amigo), veré esto:
Observación: los puntos BDFH están en la misma ubicación, pero para ilustrar el problema los coloqué en una fila al lado de la otra.
Como puede ver si sigue la secuencia A, B, C, verá que el punto B no está en la ubicación correcta.
A partir de la construcción de iOS9, casi todos los usuarios de prueba han experimentado esta situación una o dos veces en una semana.
Siguiendo algún código utilizamos:
CLLocationManager (en el hilo de la 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];
En otro método, llamo al inicio (también cuando la aplicación se inicia y la detiene cuando termina). (Hilo principal)
[_manager startUpdatingLocation];
Código para trabajar con ubicaciones (he eliminado algunos códigos para mantener el ejemplo limpio):
- (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]];
}
Se siente como un error de iOS9 en el administrador de ubicación que me está dando resultados incorrectos sobre el paradero del usuario. Si busco Stackoverflow.com parece que soy el único.
-> Ejemplo 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>
En el mapa:
Nota: A y C están en la ubicación exacta, los cambié manualmente para mostrar que A está detrás de C.
Lo siguiente es raro:
- 4rd / D tiene una hora de GPS anterior, luego apunte 3rd / C
- De alguna manera, no obtuve una ubicación para 06:27:31 pero obtuve dos 06:27:33
- 1st / A y 3rd / C tienen las mismas coordenadas de GPS. Esto no puede ser correcto porque el automóvil está conduciendo la carretera a 26 m / s (93 km / h).
El punto 3 significa que no puedo simplemente arreglarlo al mantener la última fecha de GPS y omitir todo antes de la última.
-> Ejemplo 3:
Movieron los puntos de orden dobles e incorrectos uno al lado del otro:
Acabo de volver a cargar los puntos en los que estoy interesado con las notaciones ABCD.
El archivo GPX de la captura de pantalla anterior:
<?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>
En este archivo, el problema ocurrió un par de veces, pero parece ubicarse en 2 ubicaciones problemáticas. Después de eso no hay más problemas, pero el usuario eliminó la aplicación después de algunos KM.
-> Lo he intentado:
- Estableciendo ActivityType en CLActivityTypeAutomotiveNavigation
- Configurando pauseLocationUpdatesAuto a YES
- DeseadoAccuracy to kCLLocationAccuracyBestForNavigation
- Mover todo al hilo principal y no hacer ningún cambio de hilo.
- Extender el registro para ver si mis ubicaciones de arreglo contienen más de un objeto de ubicación, pero este no es el caso.
- Registrar la ubicación HASH y Pointer, pero todas son diferentes.
-> He aprendido:
- No establezca pausesLocationUpdatesAutomatically en FALSE. Es VERDADERO por defecto y para una aplicación de navegación debería permanecer VERDADERO. Obtendrá muchas más ubicaciones cuando configure esto en FALSO, ubicaciones que no son diferentes a otra.
Establezca las propiedades en el CLLocationManager una vez, cuando cambie las propiedades a menudo extrañas y más ubicaciones llegarán al delegado. En el ejemplo: si establece estas propiedades en el método delegado didUpdateLocation, terminará con 4 ubicaciones en el mismo milisegundo.
_manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; _manager.activityType = CLActivityTypeAutomotiveNavigation;
No estoy seguro de que esta sea la historia completa, pero después de investigar durante 2 días, esto es lo que creo que está pasando.
El locationManager hará algo como lo que estás describiendo (ubicaciones duplicadas) si se recrea en cualquier momento. Esto tiene sentido de alguna manera, si crea un nuevo administrador de ubicaciones o reinicia su actual, recibirá otro conjunto de su ubicación actual. Pude obtener resultados similares creando una aplicación de juguete que recreaba el locationManager cada vez que se presionaba un botón y hacía clic en el botón regularmente.
Si el locationManager pierde la conexión de red (señal celular y wifi) no puede transmitir los datos de posición. En resumen, creo que el locationManager se está destruyendo cada vez que el dispositivo pierde la conexión a internet y cuando se recrea, momentos después, está utilizando las coordenadas anteriores. Por qué el almacenamiento en caché de estos valores y cómo las firmas de tiempo son incorrectas sigue siendo un misterio para mí.
Finalmente, creé una aplicación de juguete que usa el mismo código que usas para inicializar su locationManager (menos el código usado para almacenar las 200 ubicaciones anteriores). Todo lo que hace es poner un pin en el mapa cada vez que recibe su ubicación. Manejé alrededor y vi colocaciones inconsistentes, pero no exactamente lo que describiste. El hecho de que vi un comportamiento extraño me lleva a suponer que esto es un error con iOS 9 y no con tu código.
En este punto, considerando todos los otros errores encontrados en iOS 9 hasta ahora, creo que es justo atribuirlo a Apple.
no se puede agregar comentario ...
Todavía solo funciona bien configurando distanceFilter
Sigo tu respuesta: _locationManager.activityType = CLActivityTypeFitness; _locationManager.pausesLocationUpdatesAutomatically = YES;
_locationManager.activityType = CLActivityTypeFitness; _locationManager.pausesLocationUpdatesAutomatically = YES;
También encuentre algunos lugares cableados como este:
primero es completamente igual al tercero, porque es eso ...