Quit the application in iphone by code [duplicate] - iphone

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
how to quit (exit) an app in iPhone4 sdk
I have a close button in the first view of the app. I need to close the application succesfully on button click. I had tried the two cases but not worked.
[[UIApplication sharedApplication] terminate];
[[UIApplication sharedApplication] exit(0)];

iOS apps aren't supposed to quit on their own; the user quits/suspends apps using the devices' button. For more on this read Don't Quit Programmatically in the iOS Human Interface Guidelines.
If your app has finished whatever task it's meant to do and you would normally exit, you can instead just reset the app's state back to whatever it would be when the app starts. You should probably include some cues in the UI so that the user understands what's happening -- remember, the user is supposed to be in charge here. But if your app has reached it's logical conclusion, it may be that the thing that will feel most "right" to the user will be to go back to the initial state. You often see this with games -- once the game is done, the app goes back to the intro screen and waits for the user to start another game.
Note that both snippets you posted are incorrect. UIApplication doesn't have a -terminate method. (NSApplication does have a -terminate: method, but it takes a parameter and obviously isn't available in iOS.) Your second example mixes function call syntax with message sending syntax in a way that doesn't make any sense -- I doubt that will even compile.

Similar Thing i am also doing while i want to Quit my application after Show alert i think this may help u...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
NSLog(#"%#",alertView.title);
if(alertView.title== #"Collision failed")
{
if(buttonIndex==0)
{
//gameState = kGameStateRunning;
[self loadView];
[self viewDidLoad];
count=0;
}
else
{
exit(0);
}
}
else
{
if(buttonIndex==0)
{
//gameState = kGameStateRunning;
[self loadView];
[self viewDidLoad];
}
else
{
second_stage *obj=[[second_stage alloc]initWithNibName:#"second_stage" bundle:nil];
obj.count2=count;
[self presentModalViewController:obj animated:YES];
}
}
simply i am writing exit(0);

Just call exit(0);
No need to call with the instance of UIApplication. But before call the exit method, do whatever you need to do such as saving the state, values if any, etc.,

I am not very sure but acc to HIG, iPhone apps should not be closed.
but you can Set UIApplicationExitsOnSuspend in your application's plist.When you switch to another app, it will cause the app not to go into the background under iOS4. :)

Related

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).

iPhone, call another phone number in response to the first not answering?

I am attempting to create an application that will initiate a call to a priority 1 contact on a call-center-like list.
Then, if that contact does not answer (let's forget the whole problem of answering machines here), I'd like to call the priority 2 contact, and so on, until one of them answers or I exhaust my list.
Is this possible?
I've tried the following:
Hook into the CTCallCenter.CallEventHandler event, and checking the call state for CTCallStateConnected and CTCallStateDisconnected, and I get it to respond to the fact that the call disconnected, without ever connecting, and then attempt to initiate another call like I did the first, but this second attempt just sits dead in the water.
Override the DidEnterBackground method, and periodically check the CTCall.CallState property, basically again trying to respond to a disconnect that was never connected, but this does not appear to work either
I also tried adding a short delay (1 second, 2.5 seconds and 10 seconds) after detecting the disconnected state before attempting the next dial, to allow for the phone application to "settle down" after aborting the call, this did not change anything.
I'm of the opinion that this is better solved at the destination of the phone call. I would either have the phone company configure a "follow me" service, use Twilio or some other 3rd party service (as already suggested), or configure my own PBX using something like Asterisk (Asterisk includes the ability to configure "follow me" type behavior). It provides you much more flexibility and control, even if you did find a way to do this natively in iOS.
Having said that, I did get this to work in iOS assuming the following:
Your app initiates the call.
The phone app is opened, dials the number, and disconnects.
The user explicitly returns to your app. If you managed to get the events while your app was backgrounded, I want to know more :-).
On return of control to your app, the phone events are sent and a new call is initiated.
I have the following snippet of code in my UIApplicationDelegate didFinishLaunchingWithOptions method:
// In appdelegate header, ct is declared as #property (strong, nonatomic) CTCallCenter *ct;
self.ct = [[CTCallCenter alloc] init];
self.ct.callEventHandler = ^(CTCall *call) {
if (call.callState == CTCallStateConnected) {
// do some state management to track the call
} else if (call.callState == CTCallStateDisconnected) {
// check that this is the expected call and setup the
// new phone number
NSURL *telURL = [NSURL URLWithString:myNewNumberURL];
[application openURL:telURL];
}
};
This will make the new call. I'm using the iOS 5 SDK; tested on an iPhone 4s.
EDIT:
Using Return to app behavior after phone call different in native code than UIWebView as a starting point, I've managed to get this to work. Note that I have punted on memory management for clarity. Assuming you use the web view technique for getting back to your app after the call is complete, try something like this in the call completed block:
else if (call.callState == CTCallStateDisconnected) {
// check that this is the expected call and setup the
// new phone number
NSURL *telURL = [NSURL URLWithString:myNewNumberURL];
dispatch_async(dispatch_get_main_queue(), ^{
UIWebView *callWebview = [[UIWebView alloc] init] ;
[self.window.rootViewController.view addSubview:callWebview];
[callWebview loadRequest:[NSURLRequest requestWithURL:telURL]];
// and now callWebView sits around until the app is killed....so don't follow this to the letter.
});
}
However, this may not quite give you what you want either. The user will get an alert on each call request, providing an opportunity to cancel the call.
You could use http://labs.twilio.com/twimlets/findme. You could have the app call a Twilio number and it could use findme to call all the numbers in order.
I didn't take a deeper look at it, but the Deutsche Telekom SDK might contain what you're looking after:
http://www.developergarden.com/fileadmin/microsites/ApiProject/Dokumente/Dokumentation/ObjectiveC-SDK-2.0/en/interface_voice_call_service.html
I really am not sure though (don't have time to really look at it at the moment) - I just remembered I'd read somewhere that they have an iOS SDK that is supposed to also handle call management, so I'm posting the link here for you to find out (and hopefully tell us if it works).
#pragma mark -
#pragma mark Call Handler Notification
-(void)notificationCallHandler {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callReceived:) name:CTCallStateIncoming object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callEnded:) name:CTCallStateDisconnected object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callConnected:) name:CTCallStateConnected object:nil];
}
-(void)callEnded:(NSNotification*)notification {
NSLog(#"callEnded");
}
-(void)callReceived:(NSNotification*)notification {
NSLog(#"callReceived");
}
-(void)callConnected:(NSNotification*)notification {
NSLog(#"callConnected");
}
May this will help you
if you wanna setup a new call, while app is in background, i dont see any proper way for this, a lil hack could be, getting location update (because u can get location updates while app is in background), and location service automatically wakes up your application when new location data arrives, and small amount of time is given to application in which u can execute some code, in that time you may start a new call.
u can read further here:
search this ''Starting the Significant-Change Location Service'' in this link Location Aware programming guide
, and read the paragraph that is written after the code block.

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

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.

Simulate memory warnings from the code, possible? [duplicate]

This question already has answers here:
iOS Development: How can I induce low memory warnings on device?
(10 answers)
Closed 9 years ago.
I know i can simulate a memory warning on the simulator by selecting 'Simulate Memory Warning' from the drop down menu of the iPhone Simulator. I can even make a hot key for that.
But this is not what I'd like to achieve. I'd like to do that from the code by simply, lets say doing it every 5 seconds. Is that possible?
It is pretty easy actually, however it relies on an undocumented api call, so dont ship your app with it (even if it is in a inaccessible code path). All you have to do is use [[UIApplication sharedApplication] _performMemoryWarning];.
This method will have the app's UIApplication object post the UIApplicationDidReceiveMemoryWarningNotification and call the applicationDidReceiveMemoryWarning: method on the App Delegate and all UIViewControllers.
-(IBAction) performFakeMemoryWarning {
#ifdef DEBUG_BUILD
SEL memoryWarningSel = #selector(_performMemoryWarning);
if ([[UIApplication sharedApplication] respondsToSelector:memoryWarningSel]) {
[[UIApplication sharedApplication] performSelector:memoryWarningSel];
}else {
NSLog(#"Whoops UIApplication no loger responds to -_performMemoryWarning");
}
#else
NSLog(#"Warning: performFakeMemoryWarning called on a non debug build");
#endif
}
I wrote an apple script that will hammer the simulator with memory errors, it is a bit extreme but if your code survives, then you can be more confident...
on run
repeat 100 times
tell application "System Events"
tell process "iOS Simulator"
tell menu bar 1
tell menu bar item "Hardware"
tell menu "Hardware"
click menu item "Simulate Memory Warning"
end tell
end tell
end tell
end tell
end tell
delay 0.5
end repeat
end run
Post a UIApplicationDidReceiveMemoryWarningNotification notification to the default notification center:
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification object:nil]
Just alloc-init big objects in a loop, and never release them. That should trigger a memory warning pretty quickly, I'd imagine.

Problem with applicationShouldTerminate on iPhone

I'm having a problem with applicationShouldTerminate.
What ever I do it seams that has no effect. Any help would be
appreciated.
I'm well versed in programing but this just gives me headache. Im going
over some basic tutorials for xcode , as I'm new to mac in general, and am currently looking at a simple flashlight app.
It exists but I would like to add a alert box here with option not to
quit.
(void)applicationWillTerminate:(UIApplication *)application
{
[application setIdleTimerDisabled:NO];
}
this has no effect, alert is closed even before its created.
(void)applicationWillTerminate:(UIApplication *)application
{
[application setIdleTimerDisabled:NO];
UIAlertView *alertTest = [[UIAlertView alloc]
initWithTitle:#"This is a Test"
message:#"This is the message contained
with a UIAlertView"
delegate:self
cancelButtonTitle:#"Button #1"
otherButtonTitles:nil];
[alertTest addButtonWithTitle:#"Button #2"];
[alertTest show];
[alertTest autorelease];
NSLog(#"Termination");
}
I did some reading online and found that it should be possible to do
this with
(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
But no mater where I put that declaration I get error: syntax error
before NSApplicationTerminateReply.
There is no syntax error except that xcode seems not to recognize
NSApplicationTerminateReply as valid input.
Any sample code would be greatly appreciated.
I know this is a non-answer, but hopefully I can be helpful:
Displaying a "Really quit?"-type alert like this, even if you can pull it off technically (and I'm not sure you can), is a bad idea and is likely to either cause rejection from the App Store or, at best, an inconsistent user experience because no other apps do this.
The convention with iPhone apps is to save state if necessary, then yield control (for termination) as quickly as possible when the user hits the home button or switches apps.
To ensure a consistent experience, Apple probably has an aggressive timer in place to restrict what you can do in applicationWillTerminate. And even if they don't have a technical measure in place, they probably have an App Store approval policy to ensure that applications quit immediately when they're asked to.
applicationShouldTerminate and NSApplication do not exist on the iPhone. You have to use UIApplication.
The alert view is never shown because the 'show' method does not block, and therefore, the end of 'applicationWillTerminate' is reached immediately after you create the alert view and try to show it. I believe this is by design. You can't really begin asynchronous operations in 'applicationWillTerminate'.
With regards to the applicationShouldTerminate error, in case anyone's curious, NSApplicationTerminateReply and NSApplication seem to be deprecated...even though the OP's method is exactly how it appears in the docs!
Defining your method as the below should build with no errors:
-(BOOL)applicationShouldTerminate :(UIApplication *)application
I think I found the answer to what I wanted to do but will need to check it when I get back home.
Some directions were found here
http://blog.minus-zero.org/
The iPhone 2.0 software was recently released, and with it came the
ability for users to download native apps (i.e., not web sites)
directly to their phones from within the iPhone UI or via iTunes.
Developers (anyone who pays Apple 59GBP for the privilege) can then
write their own apps and have them available for purchase in the App
Store.
One limitation of the Apple-sanctioned SDK is that only one
application is allowed to be running at a time. This presents a
problem for apps such as IM clients, music players and other programs
whose functionality relies on being able to run in the background.
Another example (courtesy of James) would be an app that takes
advantage of the iPhone 3G's GPS chip to create a log of all the
places you visit.
However, there is a neat trick that I discovered: your app will only
get terminated if you switch away from it, and hitting the iPhone's
power button while your app is in the foreground doesn't count as
switching away. The upshot of this is you can create apps which
continue to run while the iPhone is in your pocket - perfect for the
GPS example.
Achieving this is as simple as implementing two methods in your
UIApplication delegate - applicationWillResignActive: and
applicationDidBecomeActive:. Here's a simple example to demonstrate
the effect.
In your UIApplication delegate header file, add a new ivar: BOOL
activeApp. Then, in your implementation, add the following three
methods:
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(#"resigning active status...");
activeApp = NO;
[self performSelector:#selector(sayHello) withObject:nil afterDelay:1.0];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(#"becoming the active app...");
activeApp = YES;
}
- (void)sayHello {
NSLog(#"Hello!");
if (!activeApp)
[self performSelector:#selector(sayHello) withObject:nil afterDelay:1.0];
}