0

I'm trying to build an iOS where I can update my location every x seconds and send a notification to update the UI. I get my location but the update is random. Any ideas how to add the interval ?

here is my code :

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];
    [self sendNotification :@"long"
                           :[NSString stringWithFormat:@"%.8f",location.coordinate.longitude]];
    [self sendNotification :@"lat"
                           :[NSString stringWithFormat:@"%.8f",location.coordinate.latitude]];

}
  • Why update every x seconds when the location manager can just inform you when the location is changed. – rckoenes Apr 21 '17 at 08:33
  • I need it to in an interval even if it didn't change –  Apr 21 '17 at 08:34
  • Well that is not how CoreLocation works. Thus you will have to fake it. Store the latest location in a variable and read this out every x seconds. – rckoenes Apr 21 '17 at 08:36
  • is this code in appdelegate or viewcontroller ? – KKRocks Apr 21 '17 at 08:38
  • please refer this one you will get an idea http://stackoverflow.com/questions/6347503/how-do-i-get-a-background-location-update-every-n-minutes-in-my-ios-application – Ahmed Ginani Apr 21 '17 at 08:39
  • @KKRocks this is in my Model but you can consider it as ViewController –  Apr 21 '17 at 08:39
  • As per my view, let the core location do it's job, you just fetch the location after x seconds. – Gagan_iOS Apr 21 '17 at 08:47
  • so basically I fake the result by sending the last value if there is no updates ?! –  Apr 21 '17 at 08:49
  • Yes, and do not sopt the location manager updating your location. Since sometimes it might take longer to request the location then your interval. And then you will never get the most precise location. – rckoenes Apr 21 '17 at 09:41

3 Answers3

1

Try this :

declared in .h file

@property (strong, nonatomic) NSDate *lastTimestamp;

- (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(@"update your UI");
    }
}
KKRocks
  • 8,222
  • 1
  • 18
  • 84
0

use NSTimer:

//declare global

NSTimer *ShareTimeCheck;
    int ShareSecLeft;

implement this method:

  -(void)shareTimeChecking{
        if (ShareSecLeft==0) {
            [ShareTimeCheck invalidate];
            ShareTimeCheck=nil;
        }else{
            ShareSecLeft--;
            if (ShareSecLeft==0) {
                [ShareTimeCheck invalidate];
                ShareTimeCheck=nil;
            }
        }
    }

call this one in ur location update method:

                    if (ShareSecLeft==0) {
        [ShareTimeCheck invalidate];
                        ShareTimeCheck=nil;
                        ShareSecLeft=5;

    heduledTimerWithTimeInterval:1 target:self selector:@selector(shareTimeChecking) userInfo:nil repeats:YES];

  //write ur code to update the ui. or update to server as per ur requirement.

}
NAVEEN KUMAR
  • 669
  • 6
  • 25
0

In iOS natively we can’t change the interval at which the system updates the user location. IOS updates position regularly every second, if have GPS signal.

If the application is in the foreground, we could simply stop monitoring and again start it after interval, for example using NSTimer. In this case, we have to think about the life of the application. The application runs in the background and during idle stops working.

My final procedure is use NSTimer in the background by using UIApplication:beginBackgroundTaskWithExpirationHandler:. This timer triggers periodically while the application runs in the background. You can view the following example:

#import "AppDelegate.h"

@implementation AppDelegate

BOOL locationStarted = FALSE;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //set default value after application starts
    locationStarted = FALSE;
    //create CLLocationManager variable
    locationManager = [[CLLocationManager alloc] init];
    //set delegate
    locationManager.delegate = self;

    app = [UIApplication sharedApplication];

    return YES;
}

//update location
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
    NSLog(@"Location: %f, %f", newLocation.coordinates.longtitude, newLocation.coordinates.latitude);
}

//run background task
-(void)runBackgroundTask: (int) time{
    //check if application is in background mode
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {

        //create UIBackgroundTaskIdentifier and create a background task, which starts after time
        __block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            [app endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        }];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(startTrackingBg) userInfo:nil repeats:NO];
            [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode];
            [[NSRunLoop currentRunLoop] run];
        });
    }
}

//starts when application switches to background
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    //check if application status is in background
    if ( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
        NSLog(@"start background tracking from appdelegate");

        //start updating location with location manager
        [locationManager startUpdatingLocation];
    }

    //change locationManager status after time
    [self runBackgroundTask:20];
}

//starts with background task
-(void)startTrackingBg{
    //write background time remaining
    NSLog(@"backgroundTimeRemaining: %.0f", [[UIApplication sharedApplication] backgroundTimeRemaining]);

    //set default time
    int time = 60;
    //if locationManager is ON
    if (locationStarted == TRUE ) {
        //stop update location
        [locationManager stopUpdatingLocation];
        locationStarted = FALSE;
    }else{
        //start updating location
        [locationManager startUpdatingLocation];
        locationStarted = TRUE;
        //ime how long the application will update your location
        time = 5;
    }

    [self runBackgroundTask:time];
}

//application switches back from background
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    locationStarted = FALSE;
    //stop updating
    [locationManager stopUpdatingLocation];
}

/*** other methods ***/
- (void)applicationWillResignActive:(UIApplication *)application{}

- (void)applicationDidBecomeActive:(UIApplication *)application{}

- (void)applicationWillTerminate:(UIApplication *)application{}

@end

A simpler solution might be to run the timer loop:

__block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(startTrackingBg) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
});
Bin0li
  • 168
  • 16
Sargis
  • 1,196
  • 1
  • 18
  • 31
  • What's the variable app ? –  Apr 21 '17 at 09:07
  • 1
    chogath sorry I forgot to add the AppDelegate.h code. @interface AppDelegate : UIResponder { CLLocationManager *locationManager; UIApplication *app; } – Sargis Apr 21 '17 at 09:11
  • I created a new project and I copied your code and nothing is shown in the console ! –  Apr 21 '17 at 09:17
  • 1
    To enable the permissions for location updates while the app is running a special key is needed. – Sargis Apr 21 '17 at 09:20
  • see this tutorial https://www.ioscreator.com/tutorials/requesting-permissions-core-location-tutorial – Sargis Apr 21 '17 at 09:23