lhunath / UbiquityStoreManager

Implements Core Data + iCloud, deals with all the nasty stuff and gives you a clean API.
http://lhunath.github.io/UbiquityStoreManager
Apache License 2.0
391 stars 37 forks source link

Data always loads after a long delay #49

Closed arthurperton closed 10 years ago

arthurperton commented 10 years ago

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.

arthurperton commented 10 years ago

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: mobile~945C2942-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

lhunath commented 10 years ago

Are you on iOS 7?

arthurperton commented 10 years ago

Thanks for your response.

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

lhunath commented 10 years ago

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.

lhunath commented 10 years ago

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

arthurperton commented 10 years ago

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.

lhunath commented 10 years ago

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.

henneonrails commented 10 years ago

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

arthurperton commented 10 years ago

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.

lhunath commented 10 years ago

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

arthurperton commented 10 years ago

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?

lhunath commented 10 years ago

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.

kdbdallas commented 10 years ago

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

lhunath commented 10 years ago

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.

kdbdallas commented 10 years ago

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

lhunath commented 10 years ago

Please try out 44df852