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