35 votes

Les services de localisation en arrière-plan ne fonctionnent pas sous iOS 7

J'ai récemment mis à jour mon iOS appareils à utiliser iOS 7. L'une des applications que nous développons arrière-plan utilise les services de localisation pour suivre l'emplacement de l'appareil et de tous nos testeurs ont rapporté que l'application n'apparaît plus à suivre dans l'arrière-plan sous iOS 7.

Nous avons vérifié que la semi-finition pour l'application est activée dans les paramètres de l'appareil et de la version précédente fonctionnait parfaitement sous iOS 6. Même si l'appareil a été parcouru, l'application serait de redémarrer après un emplacement de mise à jour.

Est-il autre chose qui doit être fait pour que cela fonctionne sous iOS 7?

47voto

Ricky Points 3887

Je prie de m'excuser pour le retard dans l'affichage de la solution. J'ai été très occupé au cours des derniers mois et a été pris avec ma vie personnelle jusqu'à ce que je l'avais oublié ce thread. Voici la solution que j'ai utilisé pour obtenir continu emplacement à partir de iOS 7 appareils, peu importe, il est au premier plan ou en arrière-plan.

Vous pouvez trouver la solution complète et d'une explication de blog et aussi github:-

  1. En arrière-plan de mise à Jour de la Programmation pour iOS 7

  2. Github du Projet: site de référence de mise à Jour de la Programmation pour iOS 7

Les méthodes et les Explications:-

  1. Je redémarre l'emplacement de manager toutes les 1 minutes en fonction didUpdateLocations

  2. J'autorise l'emplacement gestionnaire afin d'obtenir les emplacements de l'appareil pendant 10 secondes avant de le fermer (pour économiser la batterie).

Partielle De Code Ci-Dessous:-

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

for(int i=0;i<locations.count;i++){
    CLLocation * newLocation = [locations objectAtIndex:i];
    CLLocationCoordinate2D theLocation = newLocation.coordinate;
    CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

    if (locationAge > 30.0)
        continue;

    //Select only valid location and also location with good accuracy
    if(newLocation!=nil&&theAccuracy>0
       &&theAccuracy<2000
       &&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){
        self.myLastLocation = theLocation;
        self.myLastLocationAccuracy= theAccuracy;
        NSMutableDictionary * dict = [[NSMutableDictionary alloc]init];
        [dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"];
        [dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"];
        [dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"];
        //Add the vallid location with good accuracy into an array
        //Every 1 minute, I will select the best location based on accuracy and send to server
        [self.shareModel.myLocationArray addObject:dict];
    }
}

//If the timer still valid, return it (Will not run the code below)
if (self.shareModel.timer)
    return;

self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];

//Restart the locationMaanger after 1 minute
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self
                                                       selector:@selector(restartLocationUpdates)
                                                       userInfo:nil
                                                        repeats:NO];

//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations
//The location manager will only operate for 10 seconds to save battery
NSTimer * delay10Seconds;
delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10 target:self
                                                selector:@selector(stopLocationDelayBy10Seconds)
                                                userInfo:nil
                                                 repeats:NO];
 }

Mise à jour Mai 2014: j'ai eu quelques demandes pour l'ajout d'exemples de codes sur l'envoi de l'emplacement du serveur pendant un certain intervalle de temps. J'ai ajouté les codes exemples et également combiné à un correctif pour BackgroundTaskManager pour résoudre un problème technique pour l'exécution en arrière-plan sur une longue période de temps. Si vous avez des questions, vous êtes invités à vous joindre à nous pour une discussion ici: site de référence de mise à Jour de la Programmation pour iOS 7 avec Emplacement de mise à Jour du Serveur de Discussion

18voto

akash Points 1171

Si vous regardez la vidéo WWDC 2013 Session n ° 204 - Nouveautés du pdf multitâche, la page 15 indique clairement que les applications ne se lancent pas en arrière-plan si l'utilisateur le supprime depuis le commutateur d'applications. S'il vous plaît voir l'image,

entrez la description de l'image ici

15voto

Nikolay Tsenkov Points 376

Je pense qu'ils ont fait une optimisation (probablement à l'aide de détecteurs de mouvement), pour détecter les "relativement" stationnaire positionnement du téléphone et ils cesser de l'emplacement des mises à jour. Ce n'est qu'une spéculation, mais mes tests montrent:

  1. À partir de l'emplacement des mises à jour; (testé avec une précision de 10 et de 100 mètres, 3 fois chacun)
  2. Tournez l'écran de l'appareil hors tension pour mettre l'application en arrière-plan;
  3. Laisser l'appareil à l'arrêt (par exemple sur un bureau) pendant 30 min.

Les données que j'journal montre la géo-mises à jour arrêter de venir après ~ 15m et 30s. Avec que tout autre traitement en arrière-plan que vous faites est également terminée.

Mon appareil est un iPhone 5 avec iOS 7.

Je suis sûr à 95%, ce n'était pas le cas sur iOS 6/6.1. Où obtenir geo mises à jour avec 100 millions de précision utilisé pour vous donner assez bien continue en cours d'exécution en arrière-plan.

Mise à jour

Si vous redémarrez le directeur des lieux, toutes les 8 minutes, il doit fonctionner en permanence.

Mise à jour #2

Je n'ai pas testé cette dernière, mais c'est ainsi que j'ai repris le travail quand j'ai écrit le post. J'espère que cela est utile.

- (void)tryRestartLocationManager
{
    NSTimeInterval now = [[NSDate date] timeIntervalSince1970];

    int seconds = round(floor(now - locationManagerStartTimestamp));

    if ( seconds > (60 * 8) ) {
        [locationManager stopUpdatingLocation];
        [locationManager startUpdatingLocation];
        locationManagerStartTimestamp = now;
    }
}

7voto

androidExplorer Points 101

Un de mes iOS application doit envoyer l'emplacement de mise à jour de serveur à intervalles réguliers et l'approche suivante a travaillé pour nous....

Départ dans iOS 7:

  • une application doit avoir déjà été en utilisant les services de localisation (startUpdatingLocation) AVANT d'avoir été backgrounded pour admissibles pour l'arrière-plan de l'exécution
  • l'arrière-plan de période de grâce délai d'attente a été réduit de 10 minutes à 3 minutes
  • lieu d'arrêt des mises à jour (via stopUpdatingLocation) démarrera le 3 minutes backgroundTimeRemaining compte à rebours
  • à partir de l'emplacement des mises à jour alors qu'il est déjà dans l'arrière-plan ne sera pas réinitialiser le backgroundTimeRemaining

Donc, NE vous ARRÊTEZ PAS l'emplacement des mises à jour à tout moment...au Lieu de cela, utilisez plutôt la précision nécessaire (bel emplacement vs gros de l'emplacement). Grossier emplacement ne consomme pas beaucoup de batterie...donc cette solution permet de résoudre votre problème.

Après beaucoup de recherches en ligne, a trouvé un lien qui fournissent une solution viable pour iOS 7. La solution est comme suit:

  • Alors que l'application est toujours au premier plan, lieu de départ des mises à jour (startUpdatingLocation) mais de définir la précision et la distance de filtres à très sûr-grain (par exemple de 3 km) des mises à jour. Il est important de le faire dans le premier plan (en applicationDidEnterBackground est trop tard).
  • Lorsqu'une fine résolution est nécessaire, temporairement mis de l' la précision et la distance des filtres pour obtenir le meilleur emplacement possible, et puis revenir en arrière pour le cours-grain valeurs, mais ne cessez jamais de emplacement des mises à jour.
  • Parce que l'emplacement des mises à jour sont toujours activée, l'application ne sera pas obtenir suspendu quand il passe à l'arrière plan.

Et assurez-vous d'ajouter les éléments suivants à votre demande d'Info.plist "emplacement" à la UIBackgroundModes clé "location de services" et "gps" à la UIRequiredDeviceCapabilities clé

Crédits: http://gooddevbaddev.wordpress.com/2013/10/22/ios-7-running-location-based-apps-in-the-background/

5voto

Ricky Points 3887

J'ai trouvé un autre thread de l'Endroit de Départ dans le Gestionnaire de iOS 7 à partir de tâches d'arrière-plan du Vantail mentionné que

J'ai trouvé le problème/solution. Quand il est temps de démarrer le service de localisation et d'arrêter la tâche en arrière-plan, arrière-plan la tâche devrait être arrêté avec un retard (j'ai mis 1 seconde). Sinon, le service de localisation ne démarre pas.

Quelqu'un peut essayer et vérifier?

Nikolay, vous pouvez coller votre code ici? J'ai essayé de redémarrer le directeur des lieux, toutes les 8 minutes, mais il ne fonctionne pas en permanence.

Mise à jour:

Après la recherche Haute et Basse, j'ai trouvé la Solution d'Apple Forum!

Dans iOS 7, vous ne pouvez pas démarrer le service de localisation en arrière-plan. Si vous voulez que le service de localisation pour continuer à fonctionner en arrière-plan, vous devez démarrer en premier plan et il va continuer à s'exécuter en arrière-plan.

Si vous étiez comme moi, arrêtez le service de l'emplacement et de l'utilisation de la minuterie pour le relancer dans le fond, ça ne fonctionnera PAS.

Pour de plus amples informations, vous pouvez regarder les 8 premières minutes de la vidéo 307 de la WWDC 2013: https://developer.apple.com/wwdc/videos/

Février 2014 Mise À Jour: Je peux obtenir l'emplacement en continu à partir d'un périphérique à l'aide de iOS 7 après plusieurs mois d'essai. Vous pouvez voir la réponse complète ici: arrière-plan des Services de Localisation ne fonctionne pas sous iOS 7

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X