iPhone download / parse xml file on app launch? - iphone

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

Related

how to catch the power button and home button on iPhone?

Today I went to job interview, I encountered three questions now.they hope i provide some Solutions or
Thinking.
1.when user press Home button,app don't go back the main interface or delay 5 seconds to go back the
main interface.
2. when the screen is black ,how to auto activation screen(how to catch power button press event) .
3.how direct launch my app when iPhone is start-up
My english is very bad, i hope everyone can understand what i said above.Thank you very much
None of these are possible on an iOS device, unless it's jailbroken.
Q1 and Q2: not possible
Q3: The closest you can get to desired behaviour is kiosk (store demo) mode of operation.
See more here:
Lock-down iPhone/iPod/iPad so it can only run one app
It's not exactly what you're looking for - it limits the device to use only certain app - but to my knowledge the only way to auto-start an app without jailbraking the device.
I know that this question is old, but there are easy work arounds for every question on here that work for at least iOS 7+, although there is no way to do question 2 without using private APIs. You can successfully answer questions 1 and 3 with public API answers (although they are admittedly hacky)!!
1. When user presses home button, how do you delay 5 seconds before returning to the main screen?
Oscar Gomez's answer was spot on. While you cannot delay the UI from returning to the home screen without blocking the core run loop (which will get you rejected from the app store), you can use some background process techniques if needed to get your extra 5 seconds, just not with UI.
2. How do you catch the Power Button presses?
This is for sure using a private API, and while you can PROBABLY get into the App Store, you probably won't last long once Apple gets wind of you doing this. It is also a hack. You cannot listen directly to the power button, but you CAN listen to the screen going on or off, or both at once. Here is a small code snippet that I have in an Enterprise App:
Inside UIAppDelegate
static int const DisplayOnOffObserver = 54321876;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, &PLDisplayOnOff, CFSTR("com.apple.springboard.hasBlankedScreen"), NULL, 0);
...
return YES;
}
static void PLDisplayOnOff(CFNotificationCenterRef center, void* observer, CFStringRef name, const void* object, CFDictionaryRef userInfo) {
...
DO SOME MAGIC
...
}
- (void)applicationWillTerminate:(UIApplication *)application {
...
CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetDarwinNotifyCenter(), &DisplayOnOffObserver);
...
}
Obviously you have to have the application ALWAYS running in the background (which can get tricky) or you have to only care to do it within the time that you ask for to run in the background (which isn't hard)
First step is listening to the darwin notification for the screen being toggled on/off.
Second step is implementing the callback.
Third step is stopping listening for the call back.
NOTE: DisplayOnOffObserver is a random number (not very random in my case)
3. How can you directly launch your app when the iPhone starts up?
Assuming that by directly launch, you mean launch in the background, there is actually an Apple supported way of doing this. You first have to enable Background Services for location. Second, you have to start listening for significant location changes. I don't know how well this is documented, but as soon as the iPhone boots, it tries to get it's location. When it does this, it goes from not having a location to having one (which is a significant change). Your app will launch in the background which includes calling the application:didFinishLaunchingWithOptions: method, where you can ask for more time and start other processes to permanently run in the background until the user kills your application manually. If you do permanently run in the background using this method, you do stand a chance of being rejected by Apple.
Hope any of this helps someone! If anyone needs more information, just leave a comment and I will update my answer.
When user press Home button,app don't go back the main interface or delay 5 seconds to go back the
You can't, unless you don't want your app in the appstore... The only thing you CAN do is ask for more time to save your data before your application is terminated, but the UI experience will still be the same - the iphone will go back to the main interface.
when the screen is black ,how to auto activation screen(how to catch power button press event) .
Not possible.
3. How direct launch my app when iPhone is start-up
I don't think you can do this even, with private APIs, and of course with your app not accepted in the appstore.

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 can I improve the startup time of my app?

Why iPhone app's splash screen takes more time for loading?
Can we set the time for few second only? it takes almost one minute at the moment.
Well the splash screen is shown as long as your app is starting, meaning not returning from the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method.
If you are doing a lot of thing in this method then you should spilt up that code to do then at an other point in the start up of your app.
You should keep the startup time of your app as short as possible, start maintance code in separate thread, try lazy loading for every thing else.
The splash screen stays up until your app finishes initialising. Either speed up your initialisation code, or move the slow bits into a background task.
Are you timing this while in XCode? If you are then don't - XCode has to attach debuggers and all sorts of things before the app starts up.
To get a real time, build a release version and put it on a device. Then disconnect the device and start your app. that should give you a real-world indication of how long it will take.

Restart app when coming out of background

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.

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.