Reducing iPhone App Start Up Time - iphone

I'm trying to investigate a very long start up time for my app and could use some help. It takes about 6-7 seconds to start up and that's just FAR too long. I'm not loading any data sets or anything, but the app is a calculator so my xib does have lots of buttons and button images.
I'd like to use Instruments (or something else) to analyze where all of the time is being spent so that I can optimize, but the documentation for Instruments isn't really giving me much on specifics of how to use it for this specific problem and/or how to interpret the results.
Do you have any suggestions for how to test this? A pointer to a tutorial on how to use Instruments for this? An iTunes U video or something else?
Any suggestions are welcome!
Kenny

Palimondo asked how I eventually solved my problem... it was a bunch of small changes and I'm not truly sure where the savings came in to play and I'll explain why below.
My app is a calculator, so it has a ton of buttons. I thought at first it must be the button loading causing the problem, but as I explained in the comments above to Paul, even if I loaded 0 buttons, that only shaved 1 second off of the start up time. After changing many small things, I was able to save 3 seconds off of start up time which was good enough.
I had a background image that was a nice textured-gradient-ish image. I reduced the file size on it (changed the texture, exported it with different options).
I went from loading 100 buttons up front (it's a calculator) to loading about 15, but attempted to do it in a secret fashion so the user wouldn't notice. About 50 of the buttons aren't visible to start anyway because you have to tap a Shift button to see them, so they were easy to lazy-load. The others are visible, but I figured that the user isn't going to tap most of those right at start-up because they need to hit some numbers first. So I left all of the number pad buttons and the Clear button in the xib so they are loaded on start up but removed everything else from the xib.
That left me with a big blank area on the screen and you could actually see the buttons filling in the blank area as I lazy loaded them (filling very quickly, but you could see the blank area and then all the buttons appear). So I updated the background gradient graphic to include images of the buttons. The buttons appear to be there, but they aren't, so unless the user taps a fake button within 2 seconds they never notice a problem... and usually they just try to tap that button again anyway and by then it usually has been lazy-loaded and therefore works.

Before doing any of the above suggestions:
Is this 6-7 seconds while running from XCode? Or from starting directly by tapping it on the iPhone?
Debuggers and instruments won't help you much here, since they just add to the overhead, and won't help as much in profiling because it poisons the data you'll see.
Edit:
In terms of profiling tools, you may want to look into using Shark:
http://www.switchonthecode.com/tutorials/using-shark-to-performance-tune-your-iphone-app
It's pretty simple to use in general. It's sorta self-explanatory.

Here are couple of suggestions:
do you need all those buttons loading up at once?
do you (over)use transparencies in your images?
are the images the exact size required? Stretching (resizing) takes time to compute
do you perform any operation that is blocking the main thread?

I would measure the startup time of an empty dummy app (maybe the XCode Window-based app template) on your actual device (debugger disconnected). Then start adding your initialization code, views and objects from your app into this dummy app until you find what's slowing the startup time the most.

Related

How to extend the time displaying the launch picture of an iPhone app?

I have added a Default.png picture to my resource folder and the picture is now correctly displayed when the app is launched. But right now I have a problem that the time of the picture shown on screen is just too short and user just doesn't have enough time to take a look at the pic. And idea? Thanks
Make a viewController with an imageView containing the launch image. Then have that viewController load first, and set it to change after some fixed amount of time.
You could load the image onto the screen in the applicationDidFinishLaunching:withOptions method and then trigger a delay (using performSelector:afterDelay) to remove that image after a certain amount of time. That doesn't help you have a consistent load screen time, since the actual load time will vary per device, but it does let you pad the load time a bit.
I suppose if you want to get really fancy, you could pad the load time varying amounts depending on the device. Whatever you do I'd keep it to only an extra second or two.
Maybe you should take a look at Apples description, what the launch image is exactly for. I strongly recommend not to annoy the user with longer than needed "splash screens". Keep in mind, that there are people with devices, which don't support multi tasking. Using your app while getting text messages or other push notifications, switching to another app and back to yours is frustrating big time, if they have to wait until you think, they have payed enough attention to a (mostly) useless image.
Please, think about avoiding the use of nag screens. :)

iPhone Profiling and optimization

So I recently made some changes to one of my tableviews and I noticed that when the cells are being reloaded (coming back onto the screen one way or another) there is like a quarter to half second lag. I decided I'd use xcode 4's nice built in profiler. What I found is that during these spikes, most of the time running is being spent in gzopen and png_read_filter_row
I traced these functions in the call tree viwer all the way back to main, and it is never in any of my real code. The only questionable thing I am doing is small image files (1 per cell) each time cellForRowAtIndexPath is called.
I guess my question is this:
Is the file i/o that slow so that I should switch to caching these images in memory rather than on the file system?
How can I figure out what exactly it is thats slowing down my application so much using the profiling tool?
Thanks!
Can you load the images asynchronously - show a spinner where the image goes and fire off a background thread to display the image. This is a common solution to the "thumbnail image in a table row" problem.
I think you already have used the profiling tool to track down the problem: loading images. Admittedly, I am no expert on the profiler, but I think you know what you need to know. So implement your table a) without images b) with images loaded from files c) with images loaded asynchrously and stick with the fastest one. (I'm not trying to be glib, I'm just highly prejudiced toward getting the code out the door.)
Hope this helps.
-Mike

Placeholder strange behavior on input

I'm programming an application for iPhone. My application has a login system. In the login system (and somewhere around my app) I have some placeholder in the UITextFields.
After a couple of months working on this app, I noticed a sudden problem that arose once. If I don't write in the text fields that have placeholders nothing happens, if I write something in them, the blue bar that blinks showing where you are in the text becomes very slow. Moreover the ScrollViews that I have become EXTREMELY slow. Some other strange behavior happens when I have a wheel that lets the user pick some choice: the options of the wheel "fall" from the sky while the user rolls it.
All of this happens only if I write something in a UITextField that has some placeholder. If not, nothing of this happens.
I know this sounds REALLY strange, I used a MacOSX program to create a video of the text field becoming slow.
It's .swf.
try to do one thing.. delete this textfiled and create a new one with different name and see is this problem occurring again? also try to set breakpoints in your code and debug your code.
Are you sure you aren't leaking any memory or running an endless loop on the cpu? Try monitoring your app with Instruments and check your cpu activity and memory allocations.

How to use Sleep in the application in iphone

I have used to loading a default image in my appication. So i have set to,
Sleep(3); in my delegate.m class.
But sometimes it will take more than 6 to 7 minutes. So i want to display the image 3 seconds only and then it goes to my appilcation based on my requirements.
Which one is best way to do that?
Sleep(3) or [NSThread sleepForTimeInterval:3.0] or something else;
And i must display the image 3 seconds only. Please explain me.
(Note: And I declared setter and getter methods only in my deleagte class.)
Please explain me.
As Rob noted, Apple strongly recommends against a splash screen unless it hides some necessary behind the scenes process (like loading game graphics.) It is so strongly discouraged that some people have claimed that their apps have been rejected for using an unnecessary splash screen.
The default.png doesn't exist to create a splash screen. Instead it exist to allow you to create the illusion that your initial view loads faster than it does. You supposed to use it to provide an image of your initial view so that the enduser can begin to cognitively orient themselves to the interface. By the time they have oriented themselves to the interface and moved their finger to touch the interface, it is live.
Why? Because iPhone apps are supposed be quick in, quick out. People don't sit down to use them at a desk like a desktop. People use then on the go. Sometimes they use them in the middle of a conversation.
I tell my clients to test out the usability of their apps (except for games) while walking, riding an exercise bike etc as well as in the middle of a face-to-face and phone conversation. In those circumstances, a three second pause is a big deal and very noticeable especially if the app is a practical app. Imagine if every time you opened the Contact app you had to pause three seconds to see an Apple splash screen. You would get peeved in a hurry.
The key thing here is that an unnecessary splash screen doesn't add any value for the user. It is a selfish act on the part of the software publisher to eat the end users time so that the publisher can build brand recognition for the sole benefit of the publisher. Wasting three seconds of the users time every time they use the app adds up in a hurry. (In my experience, it also makes the user perceive that the overall app is slow and clunky.)
However, if you do want to shoot yourself in the foot or if you have a client hell bent on a splash screen, you do it like this:
The splash screen appears until the first view loads so you delay the loading of the first view. In the app delegates applicationDidFinishLaunching: method, remove all the code that loads the first view into the window. Replace it with a NSTimer. Put the code to load the first view in the timer's fire method.
With that setup the app will display the default.png as it launches, when it gets to applicationDidFinishLaunching:it will appear to pause from the end users perspective because no view will appear to replace the default.png.
You should note that the standard launch time for an app is 3-5 seconds. So you may not have to do anything to show the splash screen for 3 seconds. It might happen automatically.
Apple strictly recommends against this (using sleep in this way), especially in the scenario of showing a splash screen.
The best thing to do is create a view that looks like your Default.png file, then have that be the first NIB.. you could then set an NSTimer to transition (with animation if you want) to your main view/window/controller.

What's the best way to show the user something is loading on the iPhone?

Recently I've been looking to create some way of showing a user that something is being loaded. I'm sure anyone with an iPhone has seen this is apps before but what is the best way of doing it?
I started using UIProgressHUD, however it was pointed out to me that you shouldn't really use private (undocumented) API's.
I then I moved onto this which is a custom version called MBProgressHUD, however in my experience with this is wouldn't show the loading part when trying to call it not from a button and I found it very buggy (It wasn't very hard to crash the example code given by just clicking away).
I then went on to find this by James Brannan from his book, however I'm not quite sure why he claims this is the "proper way" of doing it when I've seen many apps in the past with what looks like the UIProgressHUD.
Does anyone have any ideas?
EDIT: This is pretty good...
Thanks
There is no one "best" way. Another way to do this is to simply put a UIView atop your main view's subviews, mark its userInteraction property and grey it out when needed. You could even add a UIActivityIndicator as a subview of this "foreground" UIView, starting its animation when needed. When your loading has finished, hide/stop the activity indicator and clear the foreground view's color.
If you are talking about loading over a network, one good thing to start with is to enable the status bar network activity indicator:
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
Note that you have to set it to NO when you are done! That should only be used to indicate network activity.
That's a bit subtle though, it's a great idea to have some kind of progress indicator IF you can tell exactly how long something is going to take - downloads where you know the size and count incoming bytes, or uploads where you also monitor bytes outgoing and know the total size.
If your call length is very small or the size is not really known (web service call is a great example) then some kind of overlay with a UIActivityIndicator can be very relaxing (you can also make a custom variant with a set of images added to a UIImage view to animate). The key is, that if possible it should not block the user from doing other things if possible.
Also if you have multiple things going on, you might want to add messages describing what state you are in (like, "adjusting image", "uploading image", etc).