Locationservice Indicator stays "on" - iphone

I have a created a small app which uses location services on the iPhone. All works well, except the fact, that sometimes, the small arrow in the info-bar stays active even if I explicitly kill the app.
I use the background mode for locationservices, thus the appDelegate methods applicationWillResignActive, applicationDidEnterBackground, applicationWillEnterForeground and applicationDidBecomeActive are implemented but do not touch the location services (well - I need them in background mode).
In that configuration applicationWillTerminate is never called; I implemented all the cleanup cleanup as stopUpdatingLocation in dealloc, as I did not find any other place appropriate for this. But still - the indicator stays on.
Any ideas?

I had the same problem - app leaving the location indicator on in the status bar.
My problem turned out to be that I had originally called the 'startMonitoringSignificantLocationChanges' method of CCLocationManager thinking that would give rough location info that I could up the resolution on when I really needed it.
Unfortunately once an app has called that method once, even if you then delete the app and re-install it it will always re-show the icon in the status bar until the app calls 'stopMonitoringSignificantLocationChanges' on CCLocationManager to unregister itself from the system - complete pain as I have to leave that code in until it has sorted itself out on the several people who were testing my app for me.
So if you get that icon stuck on with your app make sure you've matched any calls to 'startMonitoringSignificantLocationChanges' with a stop call.

if you started your location manager job with
[MyLocationManagerInstance startMonitoringForSignificantLocationChanges];
then you need to stop it with:
[MyLocationManagerInstance stopMonitoringForSignificantLocationChanges];
If you force the termination of the application, applicationWillTerminate isn't called, as, for the OS point of view, it appears as a SIGKILL.

I met a similar problem. The problem only happens on iPhone4, but works perfect on my 3GS. After looking into my code, I found that in my startUpdatingLocation method I used startUpdatingLocation and startMonitoringForRegion services, however, in my stopUpdatingLocation method I just stop updatingLocation service. I fixed this issue by turning off MonitoringForRegion as well.
#pragma mark -
#pragma mark Location methods
- (void)startUpdatingLocation
{
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringForRegion:desRegion desiredAccuracy:50.0f];
}
- (void)stopUpdatingLocation
{
[self.locationManager stopUpdatingLocation];
// !!!: fix location service indicator stuck issue
[self.locationManager stopMonitoringForRegion:desRegion];
}

Ok, problem solved. The indicator will stay on until a new location is found. Then if everything else is correct, the indicator turns off.

Related

view seems to reload itself

If I stop using my app for a long time then go back to it, it seems like the viewDidLoad method is being called again, even though I never "exited" the app (by pressing the home key twice and tapping the X) nor did I reboot the iPhone. If I just go to the home screen and then open the app again after a short time this does not happen. What is going on?
This has to do with the way that the operating system manages memory and how it deals with having many different apps open at one time. In a short summary, if your app is in the background for a long period of time, eventually, the OS will decide that it is inactive, and the memory associated with its view will be marked for reuse somewhere else where it is more needed. This is the viewDidUnload method in your view controller. Any time the viewDidUnload method is called, the viewDidLoad method will be called again so that you get a chance to reload your view before the user sees it.
Edit:
You cannot rely on this phenomenon happening every x minutes. It will only happen as the OS requires more memory for active apps. If you want to make sure the user always gets updated information when he or she resumes usage of your app, use NSNotificationCenter and register for the UIApplicationDidBecomeActive notification.
You can try to monitor the memory waring. Most of situation like this is memory warning get trigger and viewDidUnload get called after that if the view is not the top most. So when you back to that view, viewDidLoad will get called again.
You can try to override this method in UIViewController and see if memory warning get called. It maybe triggered by some other component in your application.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

applicationDidEnterBackground & applicationWillResignActive are not being called

I am creating a simple application which perform some task on main thread. I am printing process in NSLog so I can understand that my process is running or not.
Now when I press home button without starting the process (Process will be start when I tap on a button) application enters in background and my both of methods applicationDidEnterBackground & applicationWillResignActive are being called.
But when I first tap on my button and process starts on main thread after that if I press home button none of these two method being called. So my application can't know that app entered in background or not.
Even after that when I again active the app it shows me a black screen with status bar only.
Why this is happening?
Why app not entering in background?
Why apple's methods not being called?
Is there a way to solve it?
UPDATE
Here is my appdelegate class code
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
All methods have no implementation.
Thanks in advance.
I am creating a simple application which perform some task on main thread.
Don't perform long-running operations on the main thread.
The delegate callbacks happen on the main thread. If the main thread is busy, then the callbacks won't happen until you return to the "run loop".
When foregrounding your app, the OS actually displays a screenshot if available, falling back to the launch image (Default.png). The screenshot is taken after -applicationDidEnterBackground: returns, which allows you to customize what gets saved (you might want to do this for security reasons, or to hide UI elements which might not make sense to show when relaunching e.g. a countdown timer).
The black screen is probably because your app has no launch image. If your app takes more than about 10 seconds to enter the background (and it does, since the main thread is blocked), it gets killed. Except the debugger is attached and catches SIGKILL, so it's easy to miss unless you're watching Xcode.
there are some cases
if UIApplicationExitsOnSuspend key set to true in your app's Info.plist, the applicationWillResignActive method is not called when the user hits the home button. and may b some thing other. check keys here Apple keys and see if something new you added to plist. and there is no other case that you say your delegate method not calling. it may also some time due to project in appropriate behavior. try cleaning your project and rebuild.
this is going to sound strange but for those it helps. I had the same issue and cleaned my project and then it started working again.

iphone how to make sure that application launches only after it gets the user locationn

I am doing the following things to make sure that my application launches only after it gets a location update for the user.
1) My app delegate implements CLLocationManagerDelegate
2) In my app delegate didFinishLaunchingWithOptions method, I am doing
[locationManager startUpdatingLocation]
where locationManager is CLLocationManager instance and then returning YES
3) in my app delegate implemented this method
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
4) Now when didUpdateToLocation methods get called I do
[self.window addSubview:myViewController.view];
[self.window makeKeyAndVisible];
5) I have a splash page also
So this is what I see, the splash page appears for a second or two and then a plain white window appears for a second or so and then I see my myViewController.view
I want to avoid that white plain window to appear, I know it appears because in that time my phone is trying to update user current location, but I would like it to keep displaying the splash screen during that time instead of displaying the white plain window.
Add an image view with the same image you use as your splash screen to the window in MainWindow.xib.
(PS: what a horrible user experience! What will you do if the location manager fails to get a location fix? Or if it takes 30 seconds to get one? Whatever you do, your users will be gone.)
You will have to code to display a copy of the splash screen.
but you also need to consider that the user may decline the Location service permission prompt or not be in a good GPS coverage area or in Airplane mode.
I agree with others here. It can be faked, but this is terrible for the user.
If you application absolutely cannot function without user location I would suggest presenting some screen indicating that the application is locating the user. And if it fails to do so, let the user know this.
Simply making it look like the application take 30 seconds to load is going to turn away many users. So if nothing else please let them know that something is happening back there. (Or better yet, find some way of presenting useful parts of the application while the location is being determined if the app functionality allows it)

Multitasking and termination

Is there any possiblity for reacting to the event that a user kills your app via the multitasking bar if it has moved to the background? According to my observations, applicationWillTerminate: does NOT get called.
It seems to me that there is no possiblity for cleaning up before quitting in this case.
If an app needs to do any cleanup or shutdown, under iOS 4.x it should do this when the app's suspend delegate gets called, just before the app gets sent to the background, since there is no guarantee that the app will ever get any run time again, either due to user action or memory cleanup.
If the app's Deployment Target also includes iPhone OS 3.x, then it should also do cleanup in its terminate delegate, as that will get called instead of suspend.
It should get called. Are you depending on NSLog to tell you when it does get called? When an app goes into the inactive state by pressing the home button then any further NSLogs are not printed to the console. You could try showing a small UIAlertView to see of it does get called instead.

iPhone. Shouldn't hitting the home button cause UIApplicationDelegate's dealloc to be called

I have put NSLogs in all my classes including my UIApplicationDelegate subclass. I am curious - and a bit nervous - about why I am not seeing them echo anything when I press the home button. I am running in the XCode simulator.
Since iPhone/iPad runs a single app at a time, doesn't hitting the home button discard all traces of the running app?
Thanks,
Doug
Chuck is correct, the dealloc's don't matter at that point. If you want to do something as your app is expiring, implement this in your app delegate class:
- (void)applicationWillTerminate:(UIApplication *)application {
// goodbye...
}
When an app is terminated, its memory is simply freed. Dealloc is not called, it does not pass go or collect $200. This is normal and intended.
You should implement -(void)applicationWillTerminate:(UIApplication*)application{
}
this method will get called when user hit home button.
You might also want to think about the additional multitasking support that has been announced. Obviously the details are still under NDA, but pushing Home does not necessarily stop your app.
And think about the various circumstances where your app may already be terminated quickly (e.g. if a call comes in and the system runs out of RAM). Do your cleanup with the application lifecycle messages.