On 15 May 2012, at 10:05 AM, Alex Zavatone wrote:

> Was just wondering if there are any techniques to speed up the launching of 
> iOS apps.
> 
> Back in the Director day, I would create a shell executable that would launch 
> rather quickly and present a splash screen, then an animation that indicated 
> to the user that the test of the application was loading. After that, the 
> shell read a config file, loaded the rest of the app and started up.
> 
> This approach got feedback to the user as quick as possible and provided the 
> impression of a quick launching responsive app, right from the get go.
> 
> in the case that our apps start launching sluggishly (I've seen this during 
> development sometimes) are there any approaches to take along this vein?

Only some obvious things. You know them already, so maybe all you'll learn from 
me is that iOS doesn't have a "run more fast" toggle…

1. It's not a splash screen.

Using the recommended default PNGs — screenshots without localizable content — 
gives the impression that the app's functionality is coming online. "Splash 
screens" give users the impression that you are delaying their access to the 
application so you can show them advertising. Small things can infuriate people.

2. Make the application faster.

The app doesn't have to complete its initialization quickly — it only has to 
show that it's running.

a) Profile the startup

Use the Time Profiler instrument to find performance hotspots. Do this _on the 
phone_; the simulator is too fast and has too much memory to provide an honest 
profile. (Much of the startup delay in the simulator is due to debugger 
gymnastics.) If you load data during your startup, use an absurdly large 
dataset (embedding it in the app for testing purposes, if that's convenient). 
That will catch scaling issues.

b) Do all the initialization you can on a background thread.

Something I learned from an app I did for teaching purposes. It used Core Data 
internally, but at startup it loaded the CD store from a large raw-data file. 
The particular example probably not useful to you, but it illustrates the 
larger point.

My profiling showed me that some Core Data operations were irreducible. I put 
initialization in a background thread, on a thread-specific MOC. My main thread 
observed the update notifications from the background thread, and updated its 
own MOC accordingly. Objects became available to the user as soon as they 
arrived in the main database — with an NSFetchedResultsController, it looked 
pretty cool. Even if you have to block access until the whole dataset is 
loaded, the constantly-updating tables demonstrate that the app is doing 
something. 

Obviously, storing the data in a Core Data file in the first place would have 
saved this trouble, but the general point is that if you have something 
time-consuming to do, put it into the background and call back into the main 
thread to update the UI as it progresses. 

As a bonus, keeping the main thread free prevents the watchdog timer from 
killing your app after 20 seconds. (The watchdog won't kill you while debugging 
or profiling, because the development tools allow you unlimited time to debug 
the whole process.)

c) Proceed regardless

If you have a startup subprocess that is inherently time-consuming (Core 
Location, and ANY networking), use the asynchronous API, and make your UI show 
the resulting degradation in functionality gracefully (dimmed controls, 
overlaid progress/activity indicators). NEVER use the synchronous networking 
API, nor the Foundation -…WithContentsOfURL: methods (for schemes other than 
file:). Timeouts will be on the order of 30 seconds, and to repeat, the 
watchdog allows you only 20.

d) Consider not using Core Data at all.

Do you need complex indexes and searches, extensive object-relational links, or 
faulting large numbers of records to storage? If not, maybe a tree of NSArrays, 
NSDictionaries, NSSortDescriptors, and NSPredicates will work better for you. 

For smaller, less complex data sets, they're faster. How much faster, and for 
how many records, depends on exactly what you're doing, but I'd guess that the 
line could be at least N=2000.

e) Do what you can just-in-time.

If your architecture is master/detail, consider whether building detail data 
sets one at a time on demand would be less annoying than taking time out of 
startup to build N sets all at once.


        — F

-- 
Fritz Anderson -- Xcode 4 Unleashed: Coming 21 May 2012 -- 
<http://x4u.manoverboard.org/>


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to