I am new to iPhone development, i am creating a location based app. i have searched lot related to location and came to knew that use one object ( singleton pattern ) of CLLocationManager through out app, in my app i have to update user's location to server using web service,
UPDATE
as discussion with Umer i came to knew that i can use one object in appdelegate of CLLocationManager and implement delegate methods in that, and update user location to server in app delegate ,
So, is it good to do in appDelegate ??
please help.
Your locationservices will run both in foreground and background, but to allow it to run in background (when the app is open and minimized), you need to declare a special background mode in your projects "Plist" file, if I'm not wrong.
The method didUpdateToLocation will give you updates every time there is a significant movement, which you can define and adjust through various settings, such as CLLocationAccuracy (locationManager.desiredAccuracy and locationManager.distanceFilter).
Depending on what desired accuracy you ask, battery main drain quicker or not.
I don't understand what you mean with "web service". These are not web-related, they're native functionalities of iOS.
You can just call the delegate method of locationManager StartUpdatingLocation when user moves to significant distance & also call the web-service for updating User's Location.
Both Task are done in Background mode.
UPDATED ANSWER
SOURCE CODE
Related
My application triggers the iPhone Dialer and goes to background via the App Delegate.
Somewhere in the AppDelegate.m file this is called:
- (void) applicationDidEnterBackground: (UIApplication *) application
{
[self terminate];
}
When I am finished with my external app (Dialer) the application is launched again but most of the GUI parts are unresponsive.
Does it ring a bell? How could I debug this issue? Let me know if you need more info.
To be more helpful. The application is an address book that each entry is dialable and when click the iOS app is called. During the call I want to be able to open my app to browse information
I am assuming that your main issue here is that you do not consider the effects of being suspended. Please see this question: iOS 4 resume from background
Then consider reading up on an apps state cycle, which you can find here
Among the things of importance found in this article are:
To help reduce your app’s memory footprint, the system automatically purges some data allocated on behalf of your app when your app moves to the background.
The system purges the backing store for all Core Animation layers. This effort does not remove your app’s layer objects from memory, nor does it change the current layer properties. It simply prevents the contents of those layers from appearing onscreen, which given that the app is in the background should not happen anyway.
It removes any system references to cached images. (If your app does not have a strong reference to the images, they are subsequently removed from memory.)
It removes strong references to some other system-managed data caches
In other words, the state of your application might not be the one you had when you were put in the background. The entirety of this process is too large to elaborate here, and should instead be researched through the documentation provided by Apple, which I have linked to above.
You get applicationdidEnterBackground when you go into the background, but when that happens, you're trying to quit your app completely? Better than doing that there's a info.plist key that will tell the OS not to enter the background "application does not run in back ground." That will terminate your app much more gracefully.
If I init additional CLLocaitonManager instance that track user location, is It will increase the load? Or Should I using one CLLocaitonManager instance between classes?
Creating too many CLLocationManager or increasing the update intervals of the Core location services severely drains battery. So creating too many instances is not advised. Dont see a need for this.
A good practice is to init one CLLocationManager in a viewController. If moving to another viewController, then stopUpdates on the current CLLocationManager & create a new manager in the new viewController. This is one pattern.
Another pattern is to create a CLLocationManager in app delegate & make it available throughout your app. This is like a global variable. But generally avoid global declaration of this variable because it continuously consumes your battery life.
So basically if all your classes are part of only one viewController then create only one CLLocationManager & share the location updates. If not then create one for each viewController.
Location services require the presence of specific hardware on the given device. So thats why ,its doesn't matter how many instance of CLLocationManager are created. Generally avoid global declaration of this variable because it continuously consumes your battery life. Another wise stop and start each time when ever you need to finding user location.
My app runs significant location change updates in the background. However the GPS display icon never turns off..even when app is in the background. Is there a way to use location manager with Significant location change in the background and have the GPS icon NOT display continuously? My users don't understand that it is only periodically obtaining location coordinates and instead think its constantly running in background and thus deleting app thinking its too power intensive. Please help.
I believe that any use of CoreLocation will prompt the location arrow. That includes any of the geofencing CLRegion use, -startMonitoringForSignificantLocationChanges, and -startMonitoringForLocation. I think that is Apple's safeguard that something is using your GPS, even in limited use.
That arrow will be visible till you unregister your application from significant change. But I faced problem, what I can't fine point where I can do this. In my case will be best to unregister on application kill, but with multitasking there is no such ability to handle this moment to unregister.
I implemented background location tracking using standard location services, and it works fine. However, since this implementation uses a lot of power, I decided to switch to significant location changes monitoring. Basically, I just changed all the calls to startUpdatingLocation to startMonitoringSignificantLocationChanges and reused the CLLocationManagerDelegate methods I have implemented before.
The problem is that after switching to significant location changes monitoring, the delegate method locationManager:didUpdateToLocation:fromLocation only gets called once when I start monitoring, and is never called again afterwards. I have moved around the phone for a couple of kilometers, and tried riding a train with it, but still the method never gets called. Am I missing something here? Are there settings I need to enable or special code I need to write in order for this to work?
Thanks!
The significant location change requires cell phone towers in order to operate. If you don't have cell phone reception you will not get any results. You can also call CLLocationManager's significantLocationChangeMonitoringAvailable method to see if it is available.
I have a application that periodically (via an NSTimer) asks for the users location using locationManager:startUpdatingLocation I want the locationManager to run in the background so have entered "UIBackgroundModes = location" in the info.plist file.
My question is I am not seeing the results I expected, am I right in thinking that when I press the home button the application delegate calls "applicationDidEnterBackground" but although locationManager is allowed to continue my NSTimer is getting suspended (and as a consequence its not calling startUpdatingLocation to periodically query the devices position). Any ideas / solutions would be much appreciated ...
Gary.
All NSTimers are invalidated when entering the background. You need check via the CLLocationManager for any changes.
Just keep the startUpdateLocation running, you delegate will receive any major changes of the location.
When running in the background, you will only receive location changes based on cell towers.
If you read the documentation for -applicationDidEnterBackground: you'll find that yes, your timers are invalidated. Furthermore, the iOS Application Programming Guide tells you exactly how to track location from the background.