How can I use an NSTimer and applicationDidEnterBackground method at background for calling locationManager function?
Why would you need a timer? If you set your delegate to receive the callbacks from location updates, you won't need a timer. If you need active location tracking, you will be taking a huge battery hit if it runs for extended periods of time. You would be better off when you enter background to switch to -monitorForSignificantLocationChanges instead. Register your AppDelegate as as the Location Manager Delegate and just do what you need to do from the call backs.
Related
Let's say you want to focus your MapView on the current location, then you write some code in didUpdateLocation which processes the current location coordinates.
But if you don't call requestLocation or startUpdatingLocaion on your CLLocationManager object, the method never gets called. Is that correct?
But wether you call requestLocation or startUpdatingLocation if you look on your MapView the blue dot which shows your location moves (e.g. you simulate movement) but didUpdateLocation won't get called automatically.
I am trying to understand why they made a delegate method when you kind of have to call it yourself.
You have to call the startUpdatingLocation ONCE and the didUpdateLocation delegate method will be called every time when the location changes. This is very different compared to what you say.
In my app from applicationDidEnterBackground i want to ask the application for more time to
create a UIWebView and load request with UIBackgroundTaskIdentifier, then in the delegate
method of UIWebView (webViewDidFinishLoad) i want to do a stuff there and show an alert or
notification while the
application is still reining in the background .
so how i can do that?.
Apple's documentation for UIApplication class for beginBackgroundTaskWithExpirationHandler: method says:
You can call this method at any point in your application’s execution.
You may also call this method multiple times to mark the beginning of
several background tasks that run in parallel. However, each task must
be ended separately. You identify a given task using the value
returned by this method.
This method can be safely called on a non-main thread.
So, once web view finish loading in background you can trigger another operation from webViewDidFinishLoad to show alert.
When you receive applicationDidEneterBackground your app is already effectively in the background. At that moment all your networking should be closed and you really shouldn't try to show any alerts or notifications.
In my iPhone app I want to logout the user if nothing happens till about 2 minutes (e.g. the user puts down the phone). Does anybody has such issue? What is the best way to implement this feature? I think I save the date of last event to NSUserDefaults, then on the next event first I check the current date. If the difference is larger than 2 minutes go to login screen, else refresh the stored date. But how can I get the touch event generally?
Thanks, madik
There's a method in UIApplicationDelegate for that:
- (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.
*/
}
Note that it also will be called when the app is going to background state. That will help you store the data whenever the app is going to inactive state. If you want to check if a certain amount of time has passed, you will have to use a NSTimer and store the last touch event. I think it cannot be done because you can't intercept all the touch events (Maybe it's over an object managed by the system. The status bar is an example). I guess is better to let the system to manage all the activity/inactivity stuff and store your data when necessary.
EDIT: I didn't understand what you mean the first time. Check this accepted answer, it accomplish what you need. Basically you have to subclass UIApplication and override sendEvent method.
'NSTimer'
When you say "how can I get the touch event generally?", if you mean how can you tell if the user is idle or not, you'll have to set up some system to gather all touch events at a higher level in your app. You could update the last touch time you mentioned in NSUserDefaults but that may be inefficient during the run of the app, so you could just post the touch event to your main app delegate and have it save the time of last touch. Which would also be where you could set up the 2 minute timer.
Something like:
- (void) someAppDelegateMethodThatYouCallForAnyUserEvent
{
[self.idleTimer invalidate];
self.lastEvent = [NSDate now];
self.idleTimer = [NSTimer scheduledTimerWithTimeInterval:120 target:self selector:#selector(logoutAndGotoLogin) userInfo:nil repeats:NO];
...
}
You'll also have to do some cleanup in your app delegate methods when the app goes to background etc if you support that behavior.
I'm doing a simple game for the iPhone and now that is finished, I'd like to add a timer. I managed to implement the timer, but now I want to pause it when an incoming SMS or Phone Call minimize the application.
I thought that I should put the timer in the app delegate and, when applicationWillResignActive/applicationDidBecomeActive will be called, save/restore the timer object with NSUserDefaults, but I see that I can only save "raw" data, not entire objects.
How can i manage this trouble?
You'll need to store the elapsed time in a variable (I wouldn't use NSUserDefaults) and then create a new timer with the elapsed time subtracted.
See this question for some more info: How can I programmatically pause an NSTimer?
I have a simple countdown timer that updates a label every second. How do I keep state or the illusion of it when hitting the home button or when the app gets put in the background?
Actually, you don't need to run in the background if all you need to do is maintain a timer. In your app delegate's applicationWillTerminate:, create an NSDictionary containing the NSTimer's fire time and write it to a plist using -[NSDictionary writeToFile:atomically:], then read it back in using -[NSDictionary initWithContentsOfFile:] somewhere in your app delegate'sapplication:didFinishLaunchingWithOptions:.
If you are running in the background anyway, do the same in applicationDidEnterBackground: and applicationWillEnterForeground:. If you use this solution, be sure to invalidate the timer after you write the plist.