My App needs a Internet Connection which is checkt in the ViewDidLoad if there is no Internet connection I want to terminate the app when the Home Button is clickt so that the app start in its initial state next time but only in this case.
If there is a Internet connection from the start the homeButton should bring the app just to the background.
Apple does strongly discourages quitting from application programmatically.
I think you can handle your case without quitting application - when application goes to background(in applicationDidEnterBackground method of application delegate) save some flag indicating that you want to reinit it on resume, then when application comes back to foreground (applicationWillEnterForeground method in delegate) apply your initialization logic in case flag is set.
Programatically terminate an App is a behaviour that will be rejected to be published in the AppStore, as it seems that the application crashed.
If you don't mind that your application will never see the light at the AppStore, you can simply use exit(0).
When your app does not find an internet connection, switch to a view that exactly imitates your Default start-up image, then force that view to stay visible the usual amount of start-up time after any call to making your app active. You can also kill and recreate fresh all your other MVC objects during this time.
That way, no one will know that your app wasn't freshly started when brought back from the background.
Related
When I activate my WatchApp InterfaceController. First thing it does is attempt to wake up the parentApplication (or as according to documentation, activates it in the background) by calling "OpenParentApplication" method.
However, The method is unresponsive until I manually activate the app on parent iPhone. It also greets me with a "XXX Unexpectedly Quit", which means when I was calling my host App, for some reason it crashed it.
After the activation, I can freely exchange information with the "OpenParentApplication" method.
According to documentation, the method
Essentially, just calling the method should wake up the parent regardless of the reply closure.
My code is extremely type safe, with nil value causing the crash out of the question, what could it possibly be?
PS: I cannot debug the host App since I can only attach to process after the host app is launched, which it never did.
Since openParentApplication launches your application in the background, a number of methods that would automatically be called when your application launches will not have been called. For instance, in a normal launch your initial view controller will be calling viewDidLoad, viewWillAppear, viewDidAppear. If any of these methods configure critical aspects of app state on which non-interface elements rely, then your app is at high risk of crashing when launched in the background—but the app would not crash if it had been previously manually launched before openParentApplication was called.
Actually you Can debug main application after launching watch extension. After your extension started in Xcode go to Debug -> Attach process -> your main app.
This will enable you to use breakpoints and logging. If your app is missing there, try launching it on device first and then go and try attaching it again.
I am building a word game and I want to hide the board when application is suspended?
the code looks fine however it givs a strange behaviour!!,
when I suspend the app nothing will happen but when i resume the application then the board will hide!!
local onSystem = function( event )
if event.type == "applicationSuspend" then
print("suspend")
board_group.alpha = 0
end
end
Runtime:addEventListener( "system", onSystem )
Note: you might wonder how do I know how the application looks when suspended?
the answer is: by pressing the home button twice.
example
SpellTower in normal state
https://dzwonsemrish7.cloudfront.net/items/430k0c0b0y0b413d0b42/Image%202012.11.12%208:08:24%20AM.png?v=4822f549
SpellTower after pressing the home button twice
https://dzwonsemrish7.cloudfront.net/items/280a1y0r2U3W321y1B2z/Image%202012.11.12%208:08:31%20AM.png?v=09c37567
you can see how they are hiding the letters, this is exactly what I want to do for my game, the only difference is i am using Corona SDK
When you do board_group.alpha = 0 you only has set a variable, the result will only take effect after a screen update.
But since the application is suspended... it won't update! So, changing any graphics on applicationSuspend don't work.
I believe the reason is because the application is not considered as suspended. In normal objective c programming it means that applicationWillResignActive is called when the user double clicks on the home button. So what you want to do is to add that code for this part.
Here is a flow of events:
http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/
Corona seems to have these events:
"applicationStart" occurs when the application is launched and all code
in main.lua is executed.
"applicationExit" occurs when the user quits the application.
"applicationSuspend" occurs when the device needs to suspend the application such as during a phone call or if the phone goes to sleep
from inactivity. In the simulator, this corresponds to the simulator
running in the background. During suspension, no events (not even
enterFrame events) are sent to the application while suspended, so if
you have code that depends on time, you should account for the time
lost to an application being suspended.
"applicationResume" occurs when the application resumes after a suspend. On the phone, this occurs if the application was suspended
because of a phone call. On the simulator, this occurs when the simulator was in the background and now is the foreground application.
So my guess is that you have to implement it outside of the corona API.
According to the corona documents you can implement them in the delegate:
You can intercept UIApplicationDelegate events via your implementation
of the CoronaDelegate protocol.
This protocol conforms to the UIApplicationDelegate protocol. Corona's
internal delegate will call your protocol's method if it is
implemented.
Please keep in mind the following:
Methods that Apple has deprecated will be ignored.
In most cases, your class' version will be invoked after Corona's corresponding version of the UIApplicationDelegate method. There is one situation in which your version will be called before.
In situations where the app is about to suspend or go to the background, your method will be called before Corona's version, e.g.
applicationWillResignActive: and applicationDidEnterBackground:.
http://docs.coronalabs.com/native/enterprise/ios/CoronaDelegate.html
But this is just a guess. Hope it helps!
Edit:
I was thinking, something really simple you could do is catch it outside and present a "pause" screen, then just hide it when the application enters foreground.
So if you can't do that (for now), one other option is to save application state when the application is about to terminate, and then set UIApplicationExitsOnSuspend = true in your plist file. This will cause the application to exit instead of suspending, which will avoid any screenshots, effectively "hiding" the board, etc. The downfall is, the app will have to read the session state when it launches again... this is only useful if your application can be designed to actually exit without losing your state, and is quite honestly, a little extreme. That said, it may be the only way to effectively do what you're trying to do.
Other ideas would be to see if you can add a large black layer to the screen, even though the application is suspending; perhaps this will somehow trigger an internal screen update by natively setting setNeedsDisplay. Also, instead of modifying the alpha, you might consider temporarily removing all of your layers and see if that has a similar effect.
Consider an app that was in the multitask bar, and was closed, clicking on the minus sign.
What is supposed to be the behavior of this app at restart?
Does the app restart from scratch with the splash screen and without old data?
Or does the app load saved data and restart without splash screen and with previous data reloaded?
Thank you.
The application should restore its previous state in as many cases as possible. Prior to multitasking, all the applications tried to do this, to give the users the impression of multitasking. With multitasking in iOS 4, this doesn't change. You still need to do this to:
Support older devices.
Keep the user experience the same even if the user opens tons of apps and the device frees memory automatically.
If its closed then it will start from "scratch" unless you use the app delegate methods which are fired to store data and create the functionality to reload somewhere specific in your app yourself.
The splash screen will show if there is loading time needed, just like when you start an app the first time.
I think a user who clicks the minus is probably doing it, either just to clean up, or because he/she would like the app to return to it's beginning setup, just as if the device was reset.
I handle the minus, just like that, and start fresh with the splash screen. (not sure what the apple guide recommends)
This operation (tapping on minus icon) is intended for freeing memory.
When Apple has introduced multitasking in iOS, usage of memory has increased a lot!
So, why you have to tap on minus to kill application? When do you have to do this?
When your device responsiveness is too bad.
After killing (closing) application, when you restart the app, it start from scratch or resume last operation depending on how the application has developed!
For example, look at FacebookApp. If you are logged-in and quit app, at next restart it's reopen your account and last page seen!
For something like a game, I would suggest you restore the user's state ONLY IF they were in the middle of a game, else just start from scratch. However, for anything else, always start from scratch.
If you do nothing, your app will probably start from scratch at the moment.
I'm doing state miantainance code for Iphone os 4.0 using NSUserDefault class.
when i click on home and then click on application then it works but when i click on home and then press on Build and Run button it doesn't work
why is it so?
When you press the home button on iOS 4 the application is not stopped. It is suspended and put into a background state. The state of your application's UI is maintained automatically at this point.
When you hit build an go, the application is forcibly quit before being run again from Xcode.
I assume your code to save the UI state is in the applicationWillTerminate method. If this is the case, then your code will never be run on iOS 4, since this method is no longer called, (at least that's the case I've seen from my own testing and from other people's experiences). And in the case where an app is forcibly quit (ie, by Xcode when hitting build and run), the applicationWillTerminate method is bypassed.
You should, instead, implement the applicationDidEnterBackground and applicationWillEnterForeground methods.
This way, whenever the app is backgrounded, it will write it's state to the NSUserDefaults, ensuring that the state is saved before the app is quit.
On iOS 4 the only way to actually fully quit an app is using the multitasking UI (double pressing the home button) which forcibly quits apps. This is why it's important to implement the backgrounding methods above since they will be much more likely to be executed.
As a last note, it might be worth calling synchronize on the NSUserDefaults instance just after you write your UI state, just to ensure the defaults are written to disk at that time.
Is there any way to cause an app to quit instead of going to background when the home button is pressed? For security reasons, it would be better if the app did not run in background but actually closed when home is pushed. This is not for users' security, but rather for company data on the app, so it is not a user's choice. I could not find any way to quit other than forcing an exit, which Apple discourages.
See opting out of background execution in the iphone application programming guide:
"If you do not want your application to remain in the background when it is quit, you can explicitly opt out of the background execution model by adding the UIApplicationExitsOnSuspend key to your application’s Info.plist file and setting its value to YES.
When an application opts out, it cycles between the not running, inactive, and active states and never enters the background or suspended states.
When the user taps the Home button to quit the application, the applicationWillTerminate: method of the application delegate is called and the application has approximately five seconds to clean up and exit before it is terminated and moved back to the not running state."
Just go to info.plist of your project and check "Application does not run in background" to YES.
Unfortunately after trying out everything, I was still not able to see my application exiting on pressing home button. It always went into background even though UIApplicationExitsOnSuspend was YES and of type boolean in plist file and I removed the application from Simulator, restarted Xcode and Simulator and tried everything suggested.
Finally I started debugging the application and found one function which was preventing the application from exiting. The function was fairly simple and was downloading some images from network and was getting called from applicationDidFinishLaunching of appDelegate file. This function was delegating the task of creating network connection and downloading data to some other reusable class where I had the below code:
if(isBackgroundProcessingSupported){
appDelegate.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{}];
[NSURLConnection connectionWithRequest:request delegate:self];
}
So finally it turned out that the above code was responsible for putting the application into background on press of home button. When I commented the above code, my application is exiting instead of going into background.
NOTE: The code was there earlier as initially application was supporting background processing.
Hope this helps someone who is also struggling to find the reason like me.