Je cherche un moyen d'obtenir une mise à jour de l'emplacement d'arrière-plan toutes les n minutes dans mon application iOS. J'utilise iOS 4.3 et la solution devrait fonctionner pour les iPhones non jailbreakés.
J'ai essayé/envisagé les options suivantes:
CLLocationManager startUpdatingLocation/startMonitoringSignificantLocationChanges
: Cela fonctionne en arrière-plan comme prévu, en fonction des propriétés configurées, mais il ne semble pas possible de le forcer à mettre à jour l'emplacement toutes les n minutes.NSTimer
: Fonctionne lorsque l'application est exécutée au premier plan mais ne semble pas être conçue pour les tâches en arrière-planUIApplication:beginBackgroundTaskWithExpirationHandler
: Autant que je sache, cela devrait être utilisé pour terminer certains travaux en arrière-plan (également limité dans le temps) lorsqu'une application est déplacée en arrière-plan plutôt que de mettre en œuvre des processus d'arrière-plan "longs".Comment puis-je implémenter ces mises à jour régulières d'emplacement d'arrière-plan?
J'ai trouvé une solution pour l'implémenter à l'aide des Apple Forums du développeur:
location background mode
NSTimer
en arrière-plan avec UIApplication:beginBackgroundTaskWithExpirationHandler:
n
est plus petit que UIApplication:backgroundTimeRemaining
cela fonctionnera très bien. Lorsque n
est plus grand, le location manager
doit être activé (et désactivé) à nouveau avant qu'il ne reste plus de temps pour éviter que la tâche en arrière-plan ne soit supprimée.Ceci fonctionne car emplacement est l'un des trois types d'exécution en arrière-plan autorisés .
Remarque: j'ai perdu un peu de temps en testant ceci dans le simulateur où cela ne fonctionne pas. Cependant, cela fonctionne très bien sur mon téléphone.
Sur iOS 8/9/1 pour mettre à jour l'emplacement de l'arrière-plan toutes les 5 minutes, procédez comme suit:
Allez dans Projet -> Capacités -> Modes d’arrière-plan -> sélectionnez Mises à jour de lieu
Allez dans Projet -> Info -> ajoutez une clé NSLocationAlwaysUsageDescription avec une valeur vide (ou éventuellement n'importe quel texte)
Pour que la localisation fonctionne lorsque votre application est en arrière-plan et envoyez les coordonnées au service Web ou faites quoi que ce soit avec elles toutes les 5 minutes, implémentez-les comme indiqué dans le code ci-dessous.
Je n'utilise pas de tâches d'arrière-plan ou de minuteries. J'ai testé ce code avec mon appareil avec iOS 8.1 qui était resté sur mon bureau pendant quelques heures avec mon application en arrière-plan. L'appareil était verrouillé et le code fonctionnait correctement tout le temps.
@interface LocationManager () <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) NSDate *lastTimestamp;
@end
@implementation LocationManager
+ (instancetype)sharedInstance
{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
LocationManager *instance = sharedInstance;
instance.locationManager = [CLLocationManager new];
instance.locationManager.delegate = instance;
instance.locationManager.desiredAccuracy = kCLLocationAccuracyBest; // you can use kCLLocationAccuracyHundredMeters to get better battery life
instance.locationManager.pausesLocationUpdatesAutomatically = NO; // this is important
});
return sharedInstance;
}
- (void)startUpdatingLocation
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusDenied)
{
NSLog(@"Location services are disabled in settings.");
}
else
{
// for iOS 8
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
{
[self.locationManager requestAlwaysAuthorization];
}
// for iOS 9
if ([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
{
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
[self.locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *mostRecentLocation = locations.lastObject;
NSLog(@"Current location: %@ %@", @(mostRecentLocation.coordinate.latitude), @(mostRecentLocation.coordinate.longitude));
NSDate *now = [NSDate date];
NSTimeInterval interval = self.lastTimestamp ? [now timeIntervalSinceDate:self.lastTimestamp] : 0;
if (!self.lastTimestamp || interval >= 5 * 60)
{
self.lastTimestamp = now;
NSLog(@"Sending current location to web service.");
}
}
@end
Je l'ai fait dans une application que je développe. Les minuteries ne fonctionnent pas lorsque l'application est en arrière-plan, mais l'application reçoit en permanence les mises à jour d'emplacement. J'ai lu quelque part dans la documentation (je n'arrive pas à le trouver maintenant, je posterai une mise à jour quand je le ferai) qu'une méthode peut être appelée uniquement sur une boucle d'exécution active lorsque l'application est en arrière-plan. Le délégué de l'application a une boucle d'exécution active même dans le bg, vous n'avez donc pas besoin de créer votre propre boucle pour que cela fonctionne. [Je ne suis pas sûr que ce soit l'explication correcte mais c'est comme ça que j'ai compris ce que j'ai lu]
Tout d'abord, ajoutez l'objet location
pour la clé UIBackgroundModes
dans le fichier info.plist de votre application. Désormais, ce que vous devez faire, c'est lancer les mises à jour d'emplacement n'importe où dans votre application:
CLLocationManager locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;//or whatever class you have for managing location
[locationManager startUpdatingLocation];
Ensuite, écrivez une méthode pour gérer les mises à jour d'emplacement, par exemple -(void)didUpdateToLocation:(CLLocation*)location
, dans le délégué de l'application. Puis implémentez la méthode locationManager:didUpdateLocation:fromLocation
de CLLocationManagerDelegate
dans la classe dans laquelle vous avez démarré le gestionnaire de sites (puisque nous avons défini le délégué du gestionnaire de sites sur 'self'). Dans cette méthode, vous devez vérifier si l'intervalle de temps après lequel vous devez gérer les mises à jour d'emplacement s'est écoulé. Vous pouvez le faire en sauvegardant l'heure actuelle à chaque fois. Si ce temps s'est écoulé, appelez la méthode UpdateLocation à partir du délégué de votre application:
NSDate *newLocationTimestamp = newLocation.timestamp;
NSDate *lastLocationUpdateTiemstamp;
int locationUpdateInterval = 300;//5 mins
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (userDefaults) {
lastLocationUpdateTiemstamp = [userDefaults objectForKey:kLastLocationUpdateTimestamp];
if (!([newLocationTimestamp timeIntervalSinceDate:lastLocationUpdateTiemstamp] < locationUpdateInterval)) {
//NSLog(@"New Location: %@", newLocation);
[(AppDelegate*)[UIApplication sharedApplication].delegate didUpdateToLocation:newLocation];
[userDefaults setObject:newLocationTimestamp forKey:kLastLocationUpdateTimestamp];
}
}
}
Cela appellera votre méthode toutes les 5 minutes, même lorsque votre application est en arrière-plan. Imp: Cette implémentation décharge la batterie. Si la précision de vos données de localisation n'est pas critique, vous devez utiliser [locationManager startMonitoringSignificantLocationChanges]
.
Avant d’ajouter cela à votre application, veuillez lire le Guide de programmation de la détection d’emplacement
Maintenant que iOS6 est le meilleur moyen d'avoir un service de localisation permanent ...
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
NSLog(@"to background");
app.isInBackground = TRUE;
UIApplication *app = [UIApplication sharedApplication];
// Request permission to run in the background. Provide an
// expiration handler in case the task runs long.
NSAssert(bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
locationManager.distanceFilter = 100;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
NSLog(@"App staus: applicationDidEnterBackground");
// Synchronize the cleanup call on the main thread in case
// the expiration handler is fired at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
NSLog(@"backgroundTimeRemaining: %.0f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
}
Juste testé comme ça:
J'ai démarré l'application, aller en arrière-plan et me déplacer dans la voiture de quelques minutes. Ensuite, je rentre chez moi pendant 1 heure et recommence à bouger (sans ouvrir à nouveau l'application). Les emplacements ont recommencé. Puis arrêté pendant deux heures et recommencé. Tout va bien à nouveau ...
N'OUBLIEZ PAS D'UTILISER LES NOUVEAUX SERVICES DE LOCALISATION DANS iOS6
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *loc = [locations lastObject];
// Lat/Lon
float latitudeMe = loc.coordinate.latitude;
float longitudeMe = loc.coordinate.longitude;
}
Pour quelqu'un d'autre ayant un cauchemar, essayez de trouver celui-ci. J'ai une solution simple.
Ajouter une minuterie en utilisant:
-(void)applicationDidEnterBackground {
[self.locationManager stopUpdatingLocation];
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
self.timer = [NSTimer scheduledTimerWithTimeInterval:intervalBackgroundUpdate
target:self.locationManager
selector:@selector(startUpdatingLocation)
userInfo:nil
repeats:YES];
}
N'oubliez pas d'ajouter "Registres d'applications pour les mises à jour de localisation" dans info.plist.
Voici ce que j'utilise:
import Foundation
import CoreLocation
import UIKit
class BackgroundLocationManager :NSObject, CLLocationManagerDelegate {
static let instance = BackgroundLocationManager()
static let BACKGROUND_TIMER = 150.0 // restart location manager every 150 seconds
static let UPDATE_SERVER_INTERVAL = 60 * 60 // 1 hour - once every 1 hour send location to server
let locationManager = CLLocationManager()
var timer:NSTimer?
var currentBgTaskId : UIBackgroundTaskIdentifier?
var lastLocationDate : NSDate = NSDate()
private override init(){
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.activityType = .Other;
locationManager.distanceFilter = kCLDistanceFilterNone;
if #available(iOS 9, *){
locationManager.allowsBackgroundLocationUpdates = true
}
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.applicationEnterBackground), name: UIApplicationDidEnterBackgroundNotification, object: nil)
}
func applicationEnterBackground(){
FileLogger.log("applicationEnterBackground")
start()
}
func start(){
if(CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways){
if #available(iOS 9, *){
locationManager.requestLocation()
} else {
locationManager.startUpdatingLocation()
}
} else {
locationManager.requestAlwaysAuthorization()
}
}
func restart (){
timer?.invalidate()
timer = nil
start()
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case CLAuthorizationStatus.Restricted:
//log("Restricted Access to location")
case CLAuthorizationStatus.Denied:
//log("User denied access to location")
case CLAuthorizationStatus.NotDetermined:
//log("Status not determined")
default:
//log("startUpdatintLocation")
if #available(iOS 9, *){
locationManager.requestLocation()
} else {
locationManager.startUpdatingLocation()
}
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if(timer==nil){
// The locations array is sorted in chronologically ascending order, so the
// last element is the most recent
guard let location = locations.last else {return}
beginNewBackgroundTask()
locationManager.stopUpdatingLocation()
let now = NSDate()
if(isItTime(now)){
//TODO: Every n minutes do whatever you want with the new location. Like for example sendLocationToServer(location, now:now)
}
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
CrashReporter.recordError(error)
beginNewBackgroundTask()
locationManager.stopUpdatingLocation()
}
func isItTime(now:NSDate) -> Bool {
let timePast = now.timeIntervalSinceDate(lastLocationDate)
let intervalExceeded = Int(timePast) > BackgroundLocationManager.UPDATE_SERVER_INTERVAL
return intervalExceeded;
}
func sendLocationToServer(location:CLLocation, now:NSDate){
//TODO
}
func beginNewBackgroundTask(){
var previousTaskId = currentBgTaskId;
currentBgTaskId = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
FileLogger.log("task expired: ")
})
if let taskId = previousTaskId{
UIApplication.sharedApplication().endBackgroundTask(taskId)
previousTaskId = UIBackgroundTaskInvalid
}
timer = NSTimer.scheduledTimerWithTimeInterval(BackgroundLocationManager.BACKGROUND_TIMER, target: self, selector: #selector(self.restart),userInfo: nil, repeats: false)
}
}
Je lance le suivi dans AppDelegate comme ça:
BackgroundLocationManager.instance.start()
Malheureusement, toutes vos hypothèses semblent correctes et je ne pense pas qu'il y ait moyen de le faire. Afin de sauver la vie de la batterie, les services de localisation de l'iPhone sont basés sur le mouvement. Si le téléphone se trouve au même endroit, il est invisible pour les services de localisation.
La CLLocationManager
appellera uniquement locationManager:didUpdateToLocation:fromLocation:
lorsque le téléphone recevra une mise à jour de la localisation, ce qui ne se produira que si l'un des trois services de localisation (tour cellulaire, gps, wifi) perçoit un changement.
Quelques autres choses qui pourraient aider à éclairer d'autres solutions:
Le démarrage et l’arrêt des services entraînent l’appel de la méthode déléguée didUpdateToLocation
, mais il se peut que le newLocation
ait un horodatage ancien.
Lors de l'exécution en tâche de fond, sachez qu'il peut être difficile d'obtenir le support "complet" de LocationServices approuvé par Apple. D'après ce que j'ai vu, ils ont spécialement conçu startMonitoringSignificantLocationChanges
comme solution de remplacement à faible consommation d'énergie pour les applications nécessitant une prise en charge d'emplacement d'arrière-plan, et encouragent vivement les développeurs à l'utiliser sauf si elle en a absolument besoin.
Bonne chance!
MISE À JOUR: Ces idées sont peut-être obsolètes maintenant. On dirait que les gens ont du succès avec la réponse @wjans ci-dessus.
J'ai écrit une application en utilisant les services de localisation, l'application doit envoyer la localisation toutes les 10 secondes. Et cela a très bien fonctionné.
Utilisez simplement la méthode " allowDeferredLocationUpdatesUntilTraveled: timeout ", conformément au document d'Apple.
Ce que j'ai fait sont:
Obligatoire: Enregistrez le mode d'arrière-plan pour la mise à jour de l'emplacement.
1. Créez LocationManger
et startUpdatingLocation
, avec accuracy
et filteredDistance
comme vous le souhaitez:
-(void) initLocationManager
{
// Create the manager object
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
_locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
_locationManager.desiredAccuracy = 45;
_locationManager.distanceFilter = 100;
// Once configured, the location manager must be "started".
[_locationManager startUpdatingLocation];
}
2. Pour que l'application soit exécutée indéfiniment à l'aide de la méthode allowDeferredLocationUpdatesUntilTraveled:timeout
en arrière-plan, vous devez redémarrer updatingLocation
avec le nouveau paramètre lorsque l'application passe à fond, comme ceci:
- (void)applicationWillResignActive:(UIApplication *)application {
_isBackgroundMode = YES;
[_locationManager stopUpdatingLocation];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[_locationManager setDistanceFilter:kCLDistanceFilterNone];
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[_locationManager startUpdatingLocation];
}
3. L'application obtient des mises à jour comme d'habitude avec locationManager:didUpdateLocations:
callback:
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// store data
CLLocation *newLocation = [locations lastObject];
self.userLocation = newLocation;
//tell the centralManager that you want to deferred this updatedLocation
if (_isBackgroundMode && !_deferringUpdates)
{
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:10];
}
}
4. Mais vous devez gérer les données dans le callback alors locationManager:didFinishDeferredUpdatesWithError:
pour votre usage
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
//do something
}
5. REMARQUE: Je pense que nous devrions réinitialiser les paramètres de LocationManager
à chaque fois que l'application bascule entre les modes fond/arrière-plan.
if ([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
Cela est nécessaire pour le suivi de l'emplacement en arrière-plan depuis iOS 9.
J'ai utilisé la méthode de xs2bush pour obtenir un intervalle (en utilisant timeIntervalSinceDate
) et l'ai développé un peu. Je voulais m'assurer que je obtenais la précision requise et que je ne manquais pas de batterie en laissant la radio GPS allumée plus que nécessaire.
Je garde l'emplacement en cours d'exécution en permanence avec les paramètres suivants:
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locationManager.distanceFilter = 5;
il s’agit d’une consommation relativement faible de la batterie. Lorsque je suis prêt à obtenir ma prochaine lecture périodique d'emplacement, je vérifie d'abord si l'emplacement correspond à la précision souhaitée. Si c'est le cas, j'utilise ensuite l'emplacement. Si ce n'est pas le cas, j'augmente la précision avec ceci:
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
locationManager.distanceFilter = 0;
obtenir ma position et puis une fois que j'ai la position, je redéfinis la précision pour minimiser la consommation de batterie. J'ai écrit un exemple complet de travail et j'ai aussi écrit la source du code côté serveur pour collecter les données de localisation, les stocker dans une base de données et permettre aux utilisateurs d'afficher les données gps en temps réel ou de récupérer et d'afficher les itinéraires précédemment stockés. J'ai des clients pour iOS, Android, Windows Phone et Java moi. Tous les clients sont écrits de manière native et fonctionnent correctement en arrière-plan. Le projet est MIT sous licence.
Le projet iOS est ciblé pour iOS 6 à l'aide d'un SDK de base iOS 7. Vous pouvez obtenir le code ici .
Merci de signaler un problème sur github si vous constatez des problèmes. Merci.
Il semble que stopUpdatingLocation déclenche le minuteur de surveillance en arrière-plan. Je l'ai donc remplacé dans didUpdateLocation par:
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyThreeKilometers];
[self.locationManager setDistanceFilter:99999];
qui semble éteindre efficacement le GPS. Le sélecteur pour l'arrière-plan NSTimer devient alors:
- (void) changeAccuracy {
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
}
Tout ce que je fais, c'est d'inverser périodiquement la précision pour obtenir une coordonnée très précise toutes les quelques minutes et parce que le gestionnaire de localisation n'a pas été arrêté, backgroundTimeRemaining reste à sa valeur maximale. Cette consommation de batterie a été réduite d’environ 10% par heure (avec une constante kCLLocationAccuracyBest en arrière-plan) à environ 2% par heure sur mon appareil.
Il existe un cocoapod APScheduledLocationManager qui permet d'obtenir des mises à jour d'emplacement d'arrière-plan toutes les n secondes avec la précision d'emplacement souhaitée.
let manager = APScheduledLocationManager(delegate: self)
manager.startUpdatingLocation(interval: 170, acceptableLocationAccuracy: 100)
Le référentiel contient également un exemple d'application écrit en Swift 3.
Dans iOS 9 et watchOS 2.0, une nouvelle méthode sur CLLocationManager vous permet de demander l'emplacement actuel: CLLocationManager: requestLocation (). Cela se termine immédiatement, puis renvoie l'emplacement au délégué CLLocationManager.
Vous pouvez utiliser un NSTimer pour demander un emplacement toutes les minutes avec cette méthode maintenant et vous ne devez pas travailler avec les méthodes startUpdatingLocation et stopUpdatingLocation.
Toutefois, si vous souhaitez capturer des emplacements en fonction d'une modification de X mètres par rapport au dernier emplacement, il suffit de définir la propriété distanceFilter de CLLocationManger et d'appeler X startUpdatingLocation ().
Code de travail (code pas à pas complet)
étape 1
étape 2
Ajouter ce code à AppDelegate.m
@interface AppDelegate ()<CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) NSTimer *timer;
@end
Étape Ajoutez ce code dans la méthode d'applicationDidEnterBackground dans AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTaskId =
[app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTaskId];
bgTaskId = UIBackgroundTaskInvalid;
}];
dispatch_async( dispatch_get_main_queue(), ^{
self.timer = nil;
[self initTimer];
[app endBackgroundTask:bgTaskId];
bgTaskId = UIBackgroundTaskInvalid;
});
}
- (void)initTimer {
if (nil == self.locationManager)
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager requestAlwaysAuthorization];
[self.locationManager startMonitoringSignificantLocationChanges];
if (self.timer == nil) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3
target:self
selector:@selector(checkUpdates:)
userInfo:nil
repeats:YES];
}
}
- (void)checkUpdates:(NSTimer *)timer{
UIApplication *app = [UIApplication sharedApplication];
double remaining = app.backgroundTimeRemaining;
if(remaining < 580.0) {
[self.locationManager startUpdatingLocation];
[self.locationManager stopUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"Did Update Location = %f / %f", [newLocation coordinate].latitude, [newLocation coordinate].longitude);
[self updateLocationWithLatitude:[newLocation coordinate].latitude andLongitude:[newLocation coordinate].longitude];
UIApplication* app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTask =
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self initTimer];
});
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
[self.locationManager stopUpdatingLocation];
UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTask =
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
[self initTimer];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task
});
}
-(void)updateLocationWithLatitude:(CLLocationDegrees)latitude
andLongitude:(CLLocationDegrees)longitude{
//Here you can update your web service or back end with new latitude and longitude
}