How long can core data migration take on startup?
Asked Answered
H

3

6

I have seen successful core-data migrations of my 4Gb database on my iPad on application launch taking several minutes. And now suddenly, some users report crashes after installing a new version and the app is kicked out with a: failed to launch in time error.

I just tested again by restoring an old database and I am sure that core data migration can take way more than 10 seconds.

But other people are concerned it should not and try to take it to the background, or at least out of the run loop at launch time:

iPhone app launch times and Core Data migration

Can this have anything to to with other conditions, e.g. being connected to a power source? Or have a battery level of more than 50 %?

Update: I reproduced a crash by just starting the app on the device (unplugged) instead of debugging. Then I tried starting the app on the device with USB attached: Crash. Then started the app via the debugger: No crash (and the migration took about 4 minutes.)

Extra info: I have only enterprise users (about 75 of them) and they all have a database of 4.5Gb. Some users have no problem upgrading and some have. The upgrades all take minutes if they succeed. The crashes always come after 20 seconds. (And they keep crashing if you try again on these devices).

I followed the advice to place the migration out of the run loop, but I am still wondering why the old method works on some devices and not on others. All users are on iOS 7.

Haigh answered 20/1, 2014 at 13:1 Comment(1)
it really depends on the device itself and the available resources for the app e.g. ram, processor power etc. . but i recommend to handle the migration in the background, to not run in the 10 seconds startup cap.Ruche
V
6

This is a common launch problem. A Core Data migration can take any amount of time, 0 to N depending on the complexity of the model and the amount of data and the type of migration occurring.

Ideally you should not be creating your Core Data stack in the -applicationDidFinish... method and migration is one of the reasons.

My recommendation is to rework your launch so that you display something until the stack has initialized. This could be just your default image in a view. Then when the Core Data stack has initialized you can switch over to your full view controller stack.

I would also recommend taking this a bit further so that you can tell the user that a migration is in process and I would further put the migration on a background queue so that you can update the UI while the migration is happening.

Lastly, if you are doing a heavy migration, I would look into doing a lightweight migration instead. The lightweight migration is far faster as well as other benefits.

Vibrato answered 20/1, 2014 at 16:54 Comment(2)
Do you have any code samples for some of your advice in the new edition of your book? I did purchase the first version (you signed it at the Brighton conference :-), and was wondering whether buying the second edition would bring me any goodies.Haigh
There are code samples (that you could probably download from the site) that are different with an improvement to the CD stack. There is discussion about that code in V2. This specific example is not in there but will probably show up in some form soon :)Vibrato
K
1

If you look at the crash log it will likely say that the app was killed because it took too long to startup. The watchdog process kills apps that take too long to startup - >20 seconds I think. This is because the core data migration process was run during app startup.

I'd recommend you manually run the migration in the background. The following new book on Core Data has code and explanation for how to do a background manual migration.

http://www.amazon.com/gp/aw/d/0321905768

Kurtiskurtosis answered 20/1, 2014 at 23:37 Comment(2)
I will definitely look into the book. Although I already followed advice from the thread I mentioned. Just without updating UI to tell migration is in progress. My question however still is why this was no problem in the past.Haigh
I've run into the same situation. I was able to do manual migrations on startup without any issue and then with one version I started having these crashes during testing so I needed to start running the migration in the background. The migration likely completed within the allowed startup time (20 seconds) in the past but now it doesn't because you have more data or the migration is more complex.Kurtiskurtosis
A
0

It is not a rule that don't run migration on background thread, but its a suggestion because if you run on background thread and your app start running, it is not guaranteed that your core data stack will not touch.

You can take this migration out of the didFinishLaunching but make sure that stack is not touch. You can handle this by some check like place a viewController with message that app is updating which don't allow user to do anything, and at mean time you can perfrom background migration. When migration process finish you can simply dismiss that viewController take user to home viewController.

When your app is running on the iOS platform you can not gurantee every thing, like some time if native apps need more memory then memory will cut off from your app quota and can get some wired kills.

Antione answered 20/1, 2014 at 13:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.