Very enlightening Fritz.  Thanks.

One approach I took on purpose was to use a synchronous load of a JSON data set 
on startup.

I didn't want to display the main screen (TVC), until the main data had loaded 
(a 4 KB data set) and serialized.

I'm wondering if with a larger data set, the approach should be to have the 
first scene use the same graphic as the launch screen, fire off an async http 
load (through GDC or which preferred method?), display a little spinner if the 
delay takes longer then 1.25 seconds, then segue to the TVC with data when it 
loads serializes and plops itself into my data singleton.

Does that sound like a sane approach, overengineering or completely off base?

Thanks again.
- Alex Zavatone.

On May 15, 2012, at 09:20 AM, Fritz Anderson <fri...@manoverboard.org> wrote:

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