lhunath/UbiquityStoreManager

Data always loads after a long delay

arthurperton opened this issue · 16 comments

When you start the app, it always takes several seconds before the context is ready and you can display data.

For most apps this delay is not acceptable.

Other solutions show some sort of local cache right away while waiting for a connection with iCloud.

Example log on an iPhone 4S running iOS 7:

2014-01-30 13:15:24.714 Pijndagboek[8917:1403] UbiquityStoreManager: Loading store...
2014-01-30 13:15:24.719 Pijndagboek[8917:1403] UbiquityStoreManager: Will load cloud store.
2014-01-30 13:15:24.723 Pijndagboek[8917:1403] UbiquityStoreManager: Clearing stores...
2014-01-30 13:15:24.724 Pijndagboek[8917:1403] UbiquityStoreManager: Will clear stores. Notifying application to reset its UI.
2014-01-30 13:15:27.160 Pijndagboek[8917:1403] UbiquityStoreManager: Loading cloud store: E9EBC914-41ED-4592-8DE3-6042D383F433, v1 (definite).
2014-01-30 13:15:27.161 Pijndagboek[8917:1403] UbiquityStoreManager: [DEBUG] migrationStoreURL: (null)
2014-01-30 13:15:27.164 Pijndagboek[8917:1403] UbiquityStoreManager: [DEBUG] migrationStoreOptions: {
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
NSReadOnlyPersistentStoreOption = 1;
}
2014-01-30 13:15:27.479 Pijndagboek[8917:1403] UbiquityStoreManager: [DEBUG] cloudSafeForSeeding: 0
2014-01-30 13:15:27.743 Pijndagboek[8917:1403] UbiquityStoreManager: [DEBUG] Will NOT migrate to cloud store from: UbiquityStore.sqlite (strategy: 2).
2014-01-30 13:15:27.873 Pijndagboek[8917:1403] UbiquityStoreManager: Loading store: E9EBC914-41ED-4592-8DE3-6042D383F433.sqlite
2014-01-30 13:15:27.913 Pijndagboek[8917:1403] -PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:: CoreData: Ubiquity: mobile945C2942-B7DD-4C62-8AB3-29AC94798DA6:E9EBC914-41ED-4592-8DE3-6042D383F433
Using local storage: 1
2014-01-30 13:15:28.706 Pijndagboek[8917:1403] UbiquityStoreManager: Successfully loaded cloud store.
2014-01-30 13:15:28.709 Pijndagboek[8917:1403] UbiquityStoreManager: Finished loading cloud store (UbiquityStoreErrorCauseNoError). Notifying application to refresh its UI.
2014-01-30 13:15:29.477 Pijndagboek[8917:5503] -PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:: CoreData: Ubiquity: mobile
945C2942-B7DD-4C62-8AB3-29AC94798DA6:E9EBC914-41ED-4592-8DE3-6042D383F433
Using local storage: 0

Are you on iOS 7?

Thanks for your response.

Yes I am. The log is from an iPhone 4S running iOS 7.

The problem is the result of the fact that USM needs access to the cloud container to make sure another device hasn't rebuilt the cloud store before trying to open it. Accessing the cloud container the first time takes a moment since Apple does some checks if you're connected to the Internet.

Specifically, the coordinated read of the StoreUUID file which tells us which store to open:
https://github.com/lhunath/UbiquityStoreManager/blob/master/UbiquityStoreManager/UbiquityStoreManager.m#L1736

Okay, I understand and appreciate the fact that it takes a while to fully connect to iCloud.

The big question is: Using USM, can we provide the user with (the last known) data immediately? Any changes from iCloud could be applied later when they are available.

We might potentially be able to cache the StoreUUID. Alternatively, you would have to make your app handle the case where the store is not yet available, eg. by having a nice animation or by using a temporary (read-only?) local store.

@arthurperton look at the sample code and be sure to relay on the right thread. For me, I have access to data immediately.

Hi henneonrails, thanks for your reply. I will look into the sample code as soon as possible. I must say that what you are saying more or less contradicts what lhunath states above, so I am very curious what to find.

It is definitely a known issue that coordinating a read on the StoreUUID file can incur an initial delay of a few seconds.

Do you see possibilities to cache the StoreUUID as you mentioned above? And would this result in the desired user experience or are there more processes that cause delay?

Caching the StoreUUID should alleviate any delays, at least on iOS 7+ where the store loading process has been made asynchronous. On iOS 6, there are these same delays with the opening of the persistence store; which is why they weren't really a concern before (you'd have the delay anyway, whether you cached the StoreUUID or not).

Caching the StoreUUID shouldn't be too difficult. Writing it to NSUserDefaults should suffice. I don't have the time to experiment with this and the effects it has on a new device or a new account at the moment though. So unless somebody else wants to step in and play with the idea, you'll need to hang tight for a bit.

So you would store the StoreUUID in the NSUserDefaults but what would you need to update to use this before USM finishes?

the StoreUUID accesser can be simplified to just return the NSUserDefaults stored value. We'd then have to kick-start an asynchronous read on the file to update the stored NSUserDefaults and fire the appropriate storeUUIDChanged handler if the read value differs, presumably similarly to how the USMFilePresenter handles changes to the StoreUUID file's contents. After the initial read, we can rely on this file presenter to notify us of StoreUUID changes just like it happens now. Just whenever we open the store we'll need to kickstart a manual read. be it from the file presenter or in the same place as where we're creating the file presenter.

Wait was there the word "simplified" in there???? :-{

Please try out 44df852