Restart app when coming out of background - iphone

I've seen many news apps do this, where when you click on the app (on the iphone desktop) that has been in background mode, it starts again by showing a loading screen, etc. It basically looks like it starts again like it was never in background mode (I think what is called "refreshing the user interface). Does anybody know how you do this? I assume this is call from the app's delegate applicationWillEnterForeground or applicationDidBecomeActive method.

The application probably never went into the background. Try adding this to the Info.plist file.
UIApplicationExitsOnSuspend=YES
As a boolean value.

Related

In Corona SDK How to hide a group if application suspended?

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.

iPhone download / parse xml file on app launch?

I'm working on a storyboard app in which one of it's tabbed views is a mapView that downloads points from an xml file on a server. Everytime the app is launched and that tab in the tab bar controller is selected, it takes a second to download the file and parse it. Worse still, if there is no access to internet, the app crashes :/
I would like to try to use my getDataService (which downloads and parses) during the splash screen of the app instead of on ViewDidLoad of the viewcontroller (is this in appdelegate under didFinishLaunchingWithOptions?) and let it do its thing then, or in the background, and keep working in the background if the app is closed.
Then I'd like the array to be retained for future use (does this have to do with dictionaries?) and only re-download and parse the xml when the app is fully restarted.
How can I do these things? If anyone has examples or links to tutorials and examples that do these things, I'd be very grateful. I've been searching for a while, but I don't know what to search for.
Actually DO NOT do this during didFinishLaunchingWithOptions:
The reason is that iOS will kill any application that takes too long to load. I don't have the relevant documentation to hand, but iOS expects your app to finish launching within a specific period of time (I believe it's around 3 seconds or so) and if this method is not finished within that time frame you app is deemed to have hung and iOS will kill it.
The recommended technique is that if you have long running code is to start a background thread with the code on it.
The whole idea is to get the user to a usable interface as quickly as possible. Note that the debugger disables iOS's kill function, it's only active when your code is on a device and no you cannot disable it programmatically. So your code will appear to be fine when developing but fail when you run it for real.
If you need to display something whilst loading, I'd recommend putting the long running code on a background thread and continuing on to a temporary view which is basically a copy of the splash screen. then when you data is available, load up your interface.
If you do this from the AppDelegate applicationDidFinishLoading function, and assign it to a property that you define for you AppDelegate, your loading screen will still be visible while your data is being downloaded and parsed.
- (BOOL)application:(UIApplicatioN *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"loading!");
sleep(5); //delay to show you that the log happens before the loading screen goes away
return YES;
}
Make the first screen that shows when the app launches (after the Default.png splash screen) be the same or a very similar image, but give the user feedback that something is happening -- e.g. a UIActivityIndicator.
If your app doesn't fail gracefully when launched with no internet connection, Apple will reject it. Show a relevant message in this situation which advises the user something like either of these:
1) No internet connection, so functionality of this app may be limited
2) No internet connection, and this app will not function with it

MPMoviePlayerViewController gets dismissed, when app resignes active state

When I set my iPhone to sleep, switch to another app, etc., and then come back again, a prior visible MPMoviePlayerViewController (presented with presentMoviePlayerViewControllerAnimated:) is not there anymore. How can I maintain it, when my app loses the focus?
I found, that the "audio" background-mode has to be specified in the Info.plist-file to achieve the desired behavior. But interestingly my app got rejected after I added this, because it is not allowed when the app doesn't do actual background audio stuff. I think this is called a "dilemma". ;)

Is there a way to always use the default.png when returning from background?

In one of my apps when returning from background I get a non consistent behavior:
Sometimes I get the default.png and sometimes I get a snapshot of the last screen which the app was in.
In both cases it takes the UI a good second or two to respond again.
Therefore I would rather show the default.png rather then "unresponsive UI"
Is there a way to make the app display the default.png always until the app becomes active again?
Currently the "stupid" way to do it I thought about is by displaying some Modal view with the default.png and removing it on return to foreground.
Few Clarification:
I am doing this to avoid unresponsive UI.
I am using the default.png as it looks like loading and gives a better experience then unresponsive UI
The app has to run in background.
(And to whoever asked - no it is not closed when I sometimes return and see the default.png and not the last UI state - App loading from the start has a very different path and I'm sure of that)
Thanks in advance.
This is not a correct behavior and you may experiencing a bug. Basically as long as your app is in the background, when you launch it, you should not see the default.png, unless you remove it from background (double click on home button and delete that app).
For future people interested in this you can use the fact the last view in the app is used to be displayed when the app loads back.
You can display a VC as your moving to background which will represent some loading - hence achieving the desired behavior.
I've already seen a few other apps using the same behavior in cases operations are ran when coming back into the app.
Most probably, you are taking too long (performing too many calculations) in methods such as applicationWillEnterForeground:, applicationDidBecomeActive:, etc. As a simple test, try commenting out the code in these methods and see if the problem occurs again.
Simply set in your Info.plist the property "Application doesn't run in background" to YES. The app will never go in background and when the home button is pressed it will be simply terminated. So you're back to the pre-iOS4 behavior.
Note that when you see now the default image at start-up it is simply because your app has been terminated while it was in background. This is normal especially for apps that take a lot of memory and then don't free it enough before going in the background (I think the threshold for the OS is about 18MB but I'm not sure)

How to prevent my app from running in the background on the iPhone

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.