iPhone iOS 4: how do you go from background to foreground in objective-c - iphone

I am trying to make my application that is in the background come to the foreground after a call is disconnected. Here is the code:
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"tel:0123456789"]]){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:0123456789"]];
} else {
// Could not make call
}
CTCallCenter *c=[[CTCallCenter alloc] init];
c.callEventHandler=^(CTCall* call){
if(call.callState == CTCallStateDisconnected) {
// code to make app return to the foreground
// I have tried calling applicationWillEnterForeground, but it didn't work
}
}
Please help

I am fairly certain you can't do it with a simple call. Maybe registering a URL handler my app:// and usinng openURL in the completion block could work, but that seems quite hacky.

Apple will not allow you to "come to the foreground" but you can use a local notification instead.
So for what you want to do you need to:
After starting the dial url you will get a 'applicationDidEnterBackground:' as your app is pushed to the background. You will need to start a background task or else you will not get the call state change.
When you get a call state change, create a local notification. If the user wants to "view" your application then you app will come to the foreground.
There is one problem with the above, if the phone call is longer than 10 min's then the background task will be terminated you will not get your call state change.

Related

Stop setKeepAliveTimeout handler from being called after application came foreground?

For VOIP application we are sending PING packet to server every 10 minutes using setKeepAliveTimeout, everything works fine, however I'm not sure how to stop the handler from being called once application came foreground.
eg: Here is how I set the timeout
[[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }];
Background handler:
- (void)backgroundHandler
{
printf("10 minute time elapsed\n");
// do some action...
}
Above function is being called even after application came foreground, I have read in Apple documentation to set the handler nil to stop it. I have tried like below in applicationWillEnterForeground
[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:nil];
Still I'm getting call every 10 mins. How to handle this, Do I need to use flag only.
Any help is really appreciated.
you can do it like this
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
[[UIApplication sharedApplication] clearKeepAliveTimeout];
}
You have to invoke clearKeepAliveTimeout to stop the timer. setKeepAliveTimeout: is designed to keep a voip connection on and that's why it's periodically called.

How to cancel all local notifications when app is deleted from background not from device

I want to cancel all local notifications when app deleted from background, not from Device.
I know this is
[[UIApplication sharedApplication] cancelAllLocalNotifications];
but my Question is where should i pass it to fire event when application terminates from background.
I called inside applicationWillTerminateFromBackground but it is not working.
You could simply check to see if the app is in the background, and if it is, not fire the notifications.

How to know if a task is executing in background

In my app I'm downloading lots of images on a method.
I'm using a
downloadTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:downloadTask];
downloadTask = UIBackgroundTaskInvalid;
}];
This is working fine, if I press the home or sleep button, the images continue downloading.
I'm showing the progress in a UIProgressView inside an UIAlertView, and when the percent is 100% the alertView is dissmised and I change the viewController to other where I show the donwloaded images.
But I only want this to happen if the app is really active at the moment the download finish.
I have been looking at the app state and while it's downloading with the screen off.
[UIApplication sharedApplication].applicationState
the state is UIApplicationStateActive during all the donwload
How can I can know if the downloading is happening with the screen off or on?
EDITED AFTER ACCEPTING THE ANSWER:
I just discovered, if I tap the home button, the app enters in UIApplicationStateBackground, if I tap the wake/sleep it enters in UIApplicationStateInactive
Following the approach of the correct answer, my app contines donwloading in both cases.
The screen is off in two states (apart from when the app has not been even opened):
suspended : in this case you don't have to worry because the download won't procede until the app gets active again; It will enter this state on
background : it's in this state for a limited amount of time before going in suspend, and the screen is already off in this moment. Here you may want to check then whether to do all the things you said or not, because in this state code can be still executed. In this state the app status is UIApplicationStateBackground, so you could just perform a check like this:
You probably want to check whether the app is in background execution in order to achieve the result. Just like this:
if([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground) {
// Do stuff
}
If it's in background, so the screen is off.
UPDATE: after few test, what I figured out is that the behaviour you are expieriencing is probably due to the execution of the download on the main thread.
You should send the download on (for instance) the global queue. This way the application will enter the background state as expected:
....
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.bti];
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self doBackgroundStuff];
});
....
This way, if the app is put on background while the download is in progress, the application state will turn into UIApplicationStateBackground, and then you can check it as I wrote initially. If you are doing UI updates during the progress remember to send them back to the main thread (because the download is now on a different one).
You can check whether your app is running in the background or not by setting a flag in the designated application delegate methodsapplicationDidEnterBackground: and applicationWillEnterForeground:. Example:
- (void)applicationDidEnterBackground:(UIApplication *)application
_applicationRunsInForeground = NO;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
_applicationRunsInForeground = YES;
}
If you don't want to have this _applicationRunsInForeground flag inside your application delegate, you could observe the delegate's NSNotifications in your viewcontroller class instead (UIApplicationWillEnterForegroundNotification and UIApplicationDidEnterBackgroundNotification).

background task running on iphone

I have some test code which i am using to keep my app to stay running in the background state, which works quite well on the iOS 5.1 simulator but is not behaving that way on the actual device.
Now i already know the requirements i have to follow,
so i have set "background modes" to voip and location.
In my delegate's applicationDidEnterBackground method i am calling the following function
which i call "doBackgroundActivity( )"
to request time for application to complete some long running task in background :
-(void) threadedMethod{
while(true){
NSLog(#"looping");
[self showLocalNotification:#"This notification will come every 2 min. if the app is running in background. Close it!"];
[NSThread sleepForTimeInterval: (5)]; // 60 sec = 1 min
}
}
-(void) doBackgroundActivity{
self->_backgroundTask = [ [UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask: self->_backgroundTask];
self->_backgroundTask = UIBackgroundTaskInvalid;
}
];
[self threadedMethod];
[[UIApplication sharedApplication] endBackgroundTask:self->_backgroundTask];
self->_backgroundTask = UIBackgroundTaskInvalid;
}
As you see, the doBackgroundAcitivity() just calls the threadedMethod() and all that does is run an infinite loop which sends a local notification every 5 seconds or so.
Now in the simulator when i run this, and minimize the app, i see a notification every 5 seconds or so. The application keeps on running in the background even when i run other applications i see my app sending notifications.
But this is not happening on the device. It looks like that the OS kills the app just after the first notification is send and i dont see any more subsequent notifications which i expect to see later?
Is there something else i have to do to keep the application running in background ?
If all you are looking to do is present a notification to the user while your app is closed you should use UILocalNotifications.
You can set when the notification should fire, as well as whether or not it should repeat, and the amount of time between repeats.
As a side note, i wouldn't recommend using sleep() in a loop to control when code is executed like that because it stops the thread from doing anything at all, and is bad for any other tasks that would like to use that thread. Instead you should use NSTimers, and other ways of controlling the time at which code is executed.

Can an iPhone application relaunch itself when terminated?

I have two requirements for my latest project:
When the app launches for the first time it should display the device native dialer and then check for callDidConnected in background.
once the callDidConnected is true app should launch itself.
Here I tried the following logic:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
//i am dialing to a IVR from the native dialer
if (/* A check to validate wether to call or not */)
{
NSLog(#"Dialing");
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:"]];
// A loop check wether the call get connected
while (!callDidConnected){
callDidConnected = // doing a check with server
}
// if call get connected then launching my application
if (callDidConnected){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"MyApp:"]];
}
}
else
{
// normal app
}
}
- (void) applicationWillTerminate:(UIApplication *)application
{
}
I registered the app with URL MyApp.
I tested this code on simulator(on SDK 3.0/3.2) with opening another app(tried http instead of tel protocol). The check executes in background while other native app(safari) run in foreground.
"So this look a little odd" the Apple guys says.
Can any one help me to find whether I can use this code in my work, and will it be acceptable by Apple store.
No this is not possible or acceptable.
Think about it: the iPhone would not be able to do anything other than run this app, since it would instantly launch again when you quit it... Sounds like malware to me. Not something I'd ever want on my iPhone, and I'm happy that Apple restrict this kind of thing.