I had problems with timers in the background. There is no guarantee that you will have an active cycle of the cycle, so the timer will not work until you return to the forefront. I have done this:
NSRunLoop *loop = [NSRunLoop currentRunLoop]; [loop addTimer:myTimer forMode:NSRunLoopCommonModes]; [loop run];
I am doing this on a background thread inside the start and end calls of BackgroundIdentifierTask. I'm not quite sure that everything is all right with me, in fact I looked at your question to find out if the answer can help me confirm or correct my understanding of the requirements.
You must also have a background mode for the location services included in your info.pList file by default if you want to constantly monitor your location. You do not need this if you just use significantLocationUpdates or geofence.
My timer works and fires as intended in this way. Prior to that, he had not worked reliably.
Also, you might be best off without a timer. Using your code above, just change the properties of your location manager. The desired accuracy and distance filter are properties that reduce the frequency the dispatcher sends a new location notification.
See an example of my own location handler. I just wrote on github for anyone interested:
http://github.com/dsdavids/TTLocationHandler
I do not think the timer is the key. If you drop the TTLocationHandler class in your project, take a look at how the LMViewController class responds to a handler.
NSNotificationCenter *defaultNotificatoinCenter = [NSNotificationCenter defaultCenter]; [defaultNotificatoinCenter addObserver:self selector:@selector(handleLocationUpdate) name:LocationHandlerDidUpdateLocation object:nil];
sets the controller as an observer. Whenever the handler determines a new or more accurate location, handleLocationUpdate is called.
The locationManager, when startUpdating is called, will send new locations, many per second, first of all, and when moving, until the device becomes stationary and accuracy is reached. TTLocationHandler filters these events and only sends a notification as needed based on the configuration.
Notice that in - (id) init, _recencyThreshold is set to 60. Thus, we save or display the output every 60 seconds. If you want to reduce the interval, change this.
Be that as it may, the TTLocationHandler will always switch to significant changes in location in the background if the device is not plugged in. You will not get such a small interval between updates if it is charged on battery, but you will get updates.
I added a property to configure for continuous background updating without charging.
TTLocationHandler example
I added another class to the repository to show how I will achieve your goals using my handler. I added the LMPinTracker class, where you can add your code to store and load locations.
Take a look at LMAppDelegate.m
self.pinTracker.uploadInterval = 30.00;
change this to any length of time between uploads to the server.
self.sharedLocationHandler.recencyThreshold = 5.0;
Change the value of 5.0 to the minimum time between saved locations. This will be inaccurate, it will vary depending on the speed and signal strength, but basically, after an interval of x seconds, it will consider the stored location obsolete and try to get a different exact location.
Now look at the LMPinTracker.m file
Put your data storage code right after these two lines:
Put your web upload code right here after this comment:
// Do your upload to web operations here
Comments
This should do what you are looking for while maintaining battery and background charge.
Basically, when a user travels, updates will be continuous at approximately the interval you set.
When the user is in a stationary state, there will be no updates or significant actions.
When there is no new action, you will not upload it to the Internet.
Registration and updating resume when the user starts moving again.
If I were you, hoping to improve it further, I would think about creating a region and time for verification. If the user remains motionless for a certain period of time, switch only to significant values ββof LocationUpdates. Then you will turn off location services, but they will come back when the user is started again.