Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UbiquityStoreManager iOS 8 issue #73

Open
ChristianRo opened this issue Sep 12, 2014 · 46 comments
Open

UbiquityStoreManager iOS 8 issue #73

ChristianRo opened this issue Sep 12, 2014 · 46 comments

Comments

@ChristianRo
Copy link

Hi,

yesterday i updated my iPad to iOS 8. From then on the sync for core data with my iOS 8 emulator doesn't work anymore. For a test I have downloaded your sample project. With that project running on my iPad and on the emulator syncing won't work either.

So my questions are:

  • Why is the UbiquityStoreManager not compatible with iOS 8?
  • Is it possible to keep compatibility between iOS 7 and iOS 8?
  • Are there some points to concern about to provide compatibility between iOS 7 and 8? And does the upgrade from iOS 7 to iOS 8 require some specific steps to be done?

kind regards,
Christian

@mutedan
Copy link

mutedan commented Sep 14, 2014

Hi @ChristianRo, Any progress on this one?

@neilt
Copy link

neilt commented Sep 15, 2014

It appears to me that Apple is rushing Xcode 6/iOS 8 to meet the iPhone ship schedule. I’ve had so many problems in the simulator with Xcode 6 that I am only testing on devices now. The one project that I have tried on Xcode 6 that uses UbiquityStoreManager won’t even build because it can find a valid provisioning profile, Xcode offers to fix the problem, then can’t find the fix in and endless cycle.

Neil

On Sep 14, 2014, at 10:01 AM, Dan iOSub [email protected] wrote:

Hi @ChristianRo, Any progress on this one?


Reply to this email directly or view it on GitHub.

@last-Programmer
Copy link

I am also facing the issue. Enabling the icloud works fine and it seems to be data is uploaded to icloud. but when we reinstall the application and enable the icloud the data is not being synced from icloud. This happens both in simulator and device. when i enable the icloud in second device also the data is not being downloaded. the database stays empty always when we reenable the icloud or enable it on secondary device.

I get this error message in the logs.

CoreData: iCloud: Error: failed to receive initial sync notification call back in 90 seconds

PFUbiquityFilePresenter processPendingURLs]_block_invoke(439): CoreData: Ubiquity: Librarian returned a serious error for starting downloads Error Domain=BRCloudDocsErrorDomain Code=6 "The operation couldn’t be completed. (BRCloudDocsErrorDomain error 6 - Path is outside of any CloudDocs container, will never sync)" UserInfo=0x145d8970 {NSFilePath=/var/mobile/Containers/Data/Application/C5D36B00-A9D6-4558-B02D-B783CE811DB5/Library/Application Support/CloudStore/CoreDataUbiquitySupport/mobile0A1965CD-FE2F-47A6-8BC0-39CF52EA243C/C24ECE7A-AF57-49E4-B941-85F8D8B8B805/F30AA09C-B8E5-4FD3-AE38-44D6E0A3FE28/container/mobile0A1965CD-FE2F-47A6-8BC0-39CF52EA243C/C24ECE7A-AF57-49E4-B941-85F8D8B8B805/CaHRfaDrPBVrD7nNIB3JEeeJXAeedQlihaZzvtM2VTk=/D3C6DC7D-391C-414F-ABEF-015EC007E989.1.cdt, NSDescription=Path is outside of any CloudDocs container, will never sync} with userInfo {
NSDescription = "Path is outside of any CloudDocs container, will never sync";
NSFilePath = "/var/mobile/Containers/Data/Application/C5D36B00-A9D6-4558-B02D-B783CE811DB5/Library/Application Support/CloudStore/CoreDataUbiquitySupport/mobile0A1965CD-FE2F-47A6-8BC0-39CF52EA243C/C24ECE7A-AF57-49E4-B941-85F8D8B8B805/F30AA09C-B8E5-4FD3-AE38-44D6E0A3FE28/container/mobile0A1965CD-FE2F-47A6-8BC0-39CF52EA243C/C24ECE7A-AF57-49E4-B941-85F8D8B8B805/CaHRfaDrPBVrD7nNIB3JEeeJXAeedQlihaZzvtM2VTk=/D3C6DC7D-391C-414F-ABEF-015EC007E989.1.cdt";
} for these urls: (
"file:///var/mobile/Containers/Data/Application/C5D36B00-A9D6-4558-B02D-B783CE811DB5/Library/Application%20Support/CloudStore/CoreDataUbiquitySupport/mobile0A1965CD-FE2F-47A6-8BC0-39CF52EA243C/C24ECE7A-AF57-49E4-B941-85F8D8B8B805/F30AA09C-B8E5-4FD3-AE38-44D6E0A3FE28/container/mobile0A1965CD-FE2F-47A6-8BC0-39CF52EA243C/C24ECE7A-AF57-49E4-B941-85F8D8B8B805/CaHRfaDrPBVrD7nNIB3JEeeJXAeedQlihaZzvtM2VTk=/D3C6DC7D-391C-414F-ABEF-015EC007E989.1.cdt"
)

@NorbNorb
Copy link

@lhunath : I know you will no longer maintain this project, but it would be kind if you could help us with only this one issue that came up with iOS 8 so we're all back in safe waters.

@polarneo
Copy link

@NorbNorb I am facing the same dilemma as you. Have you found any solution to this or how you may proceed?

@lhunath
Copy link
Owner

lhunath commented Sep 24, 2014

You could try omitting the NSPersistentStoreUbiquitousContentURLKey, then figure out where iCloud is storing its cdt (logs) by default, and then updating -URLForCloudContentDirectory to match. Perhaps all that's needed is to replace the "CloudStore" (USMCloudStoreDirectory) with "CloudDocs" or "CloudDocs/CloudStore".

@last-Programmer
Copy link

Thank you for the reply. I tried omitting NSPersistentStoreUbiquitousContentURLKey and log files are stored in data ▸ Library ▸ Mobile Documents ▸ [container id] ▸ CoreData ▸ B710D35F-19AD-485A-A2A5-5560F80753B1 ▸ nobody~sim4653E601-3EE9-5183-A41D-D38CF3788BD3 ▸ B710D35F-19AD-485A-A2A5-5560F80753B1

First i enabled icloud in iphone 6 simulator by omitting NSPersistentStoreUbiquitousContentURLKey and see that log files are created in the above mentioned directory.

Then i enabled icloud in iphone 6 plus simulator and found that the data i added in iphone 6 simulator is not imported.

This happens in both cases with or without NSPersistentStoreUbiquitousContentURLKey

I have also tried the default container and customer in the capabilities screen. It is the same.

I tried this simple sample https://github.com/versluis/Core-Data-iCloud and its works fine. The code here seems to be same but i am unable to identify where we have to make changes to be compatible with ios8.

@NorbNorb
Copy link

@lhunath: We're really facing huge problems due to this. Do you think you can give us a hand on this topic?

@lhunath
Copy link
Owner

lhunath commented Sep 30, 2014

The store does not sync without NSPersistentStoreUbiquitousContentURLKey? What is the error?

@last-Programmer
Copy link

I am not getting any error when i omit NSPersistentStoreUbiquitousContentURLKey. I tried upgrading the UbiquityStoreManagerExample to ios8 entitlements and facing the same issue but no errors are getting logged.It would be really very helpful to us if you could suggest a way to proceed way further on this issue.

@lhunath
Copy link
Owner

lhunath commented Sep 30, 2014

Compare the application's container on both devices and on developer.icloud.com to find out what is different. They should all be identical. Turn on verbose ubiquity logging and look through that for clues. Your destination device should show logs for downloading and importing cdt files. Consider my parseLogs to filter the noise a bit though it may be outdated a bit now.

@last-Programmer
Copy link

developer.icloud.com shows only ios7 cloud containers and it does not show the cloud drive containers which is used in ios8. I have actually upgraded to cloud drive.

@lhunath
Copy link
Owner

lhunath commented Sep 30, 2014

I don't know anything at all about cloud drive or how it affects Core Data.

@polarneo
Copy link

For me the main problem was that something was getting stuck in my delegates implementation of - (void)ubiquityStoreManager:(UbiquityStoreManager *)manager willLoadStoreIsCloud:(BOOL)isCloudStore

The console output was "Stores will change. Notifying application to reset its UI." And then it got stuck.

It got stuck at
[managedObjectContext performBlockAndWait:^{

So I tested to change it to performBlock instead of performBlockAndWait
[managedObjectContext performBlock:^{

And it worked.

Don't know the implications of this change however. Or if this is related to any of your problems.

Just wanted to let you know.

@lhunath
Copy link
Owner

lhunath commented Sep 30, 2014

@polarneo do you have a working iCloud sync with USM on iOS 8?

@polarneo
Copy link

Yes, after making this change it seems like iCloud sync is working with USM and iOS 8 (and updated to iCloud Drive).

However my old data seems to be gone for some reason. Or probably it's me who broke something in my trial and error testing to get this to work. I have however created new records in iCloud with my above mentioned change. Tried to reproduce the issue by doing the following:

  1. Download the old version of my app,
  2. Opened that and enabled iCloud to see that it got stuck (see above) and didn't show any iCloud records
  3. Replaced it with my modified version (debugging from xcode)
  4. Turned on iCloud in my app again and my "newly" created data was loaded and it didn't get stuck. So I take it for that it works.

I will however test this again on another iCloud account which isn't updated to iCloud Drive and iOS 8 yet. Probably won't have time for that until thursday, but will let you know how that went, if you are interested. And hopefully the data form the old ubiquity container will also be there then.

And as I said above I don't know which implications changing from performBlockAndWait to performBlock will have. The call to [managedObjectContext reset]; will happen in another order possibly. Do you know if this might be any problem?

I could also tell when first beginning to investigate what was going wrong I thought that I had to change container names prefix from $teamidentifier to iCloud. But then I realized I shouldn't do any changes to either my containers or entitlements (told by Apple support).

So at the moment I haven't made any changes to NSPersistentStoreUbiquitousContentURLKey.

@last-Programmer
Copy link

@polarneo I tried it and it did not work for me. Did you try deleting the application and re-install and enable icloud to see it working?

@flashfm
Copy link

flashfm commented Oct 5, 2014

My app also got stuck on iOS8.
Changing to performBlock helped me and data was not lost.

@polarneo
Copy link

polarneo commented Oct 6, 2014

@rbmanian75 Sorry for late reply. Yes I deleted my app, re-installed and enabled iCloud once more. The data was there.

I also the other day tested to upgrade another account to ios8 and iCloud Drive, and it worked, I mean the data was there and it was possible to sync new data as well.

@last-Programmer
Copy link

@polarneo I also confirm that it worked after changing to performBlock in both development mode and adhoc distribution mode. Thank You.

@lhunath Will there be any consequences of this change?

@pascalfribi
Copy link

Hi all,

I have just added a pull request for a change. I need to be able to run performBlockAndWait in the willLoadStore:isICloud delegate, as otherwise my app will crash from time to time when switching stores. So I investigated the code and found, that there is no need that the method fireBeginLoadingLogReason: needs to be run on the persistentStorageQueue. So I just removed the code and now the delegates do not block anymore.

Feel free to comment on this.

@lhunath
Copy link
Owner

lhunath commented Jan 21, 2015

I can't accept this change: it causes willLoadStore:isICloud: to run on an arbitrary thread - yes, it won't block, but it'll also break the thread model.

Please share the stack of all threads while the application is in deadlock.

@pascalfribi
Copy link

You are free to come up with a better solution. Fact is, that the code is in deadlock. I do not see a reason why this code should run on this thread as it only calls the delegate who will try to run his stuff on the thread it needs. And it cancels a block operation. It would already be ok if the call [self enqueue:^{ [self fireBeginLoadingLogReason:reason]; } waitUntilFinished:YES lock:NO]; could be called with waitUntilFinished:NO.

What do you think? Then the call is done on the persistentStorageQueue and it will not block anymore.

I just cannot afford to exchange performBlockAndWait with performBlock in my delegate for willLoadStore:isICloud.

By the way: too bad you are resigning maintenance. Still the best API for Core Data with iCloud :-)

@lhunath
Copy link
Owner

lhunath commented Jan 21, 2015

Setting waitUntilFinished to NO is perhaps a good work-around, I don't know the full consequences.

Ideally, I'd prefer to understand WHY the app deadlocks, instead of just closing our eyes to the cause and trying random things to make it go away. As such, since I don't have an app anymore that uses USM, or any time to really jump into a project and try to reproduce the bug, I'm happy to at least look into the threads and their stacks involved in the deadlock to see if there's an obvious cause. If somebody can reproduce the issue and show me the state of all threads, that'd be great.

@pascalfribi
Copy link

I will send you this this evening.

Am 21.01.2015 um 18:02 schrieb Maarten Billemont [email protected]:

Setting waitUntilFinished to NO is perhaps a good work-around, I don't know the full consequences.

Ideally, I'd prefer to understand WHY the app deadlocks, instead of just closing our eyes to the cause and trying random things to make it go away. As such, since I don't have an app anymore that uses USM, or any time to really jump into a project and try to reproduce the bug, I'm happy to at least look into the threads and their stacks involved in the deadlock to see if there's an obvious cause. If somebody can reproduce the issue and show me the state of all threads, that'd be great.


Reply to this email directly or view it on GitHub.

@pascalfribi
Copy link

Hi Marten,

below you find the queue states. I have also attached an image from Xcode as this is easier to read. The situation happens always on OS X 10.10 and iOS 8.

Now as I understand this, the following happens:

  • The persistentStorageQueue triggers the delegate willLoadStore:isICloud in the method fireBeginLoadingLogReason (first time)
  • this delegate calls [managedObjectContext performBlockAndWait]. As the moc runs on the main thread and we are still in the persistentStorageQueue this Block will be put on the main queue.
  • Now we go through the main loop. Before the Block is invoked, there is already the second notification coming in (Switch from use local store: 1 to use local store: 0)
  • This notification is processed again in fireBeginLoadingLogReason on the main queue. This wlll enqueue the routine again on the persistentStorageQueue but is forced to wait until the call terminates
  • Now the 2 queues are waiting for each other to finish and we have a deadlock.

So I think by simply not forcing the method fireBeginLoadingLogReason to wait until the delegate is through will be enough to keep it running. What do you think?

Thread 1Queue : com.apple.main-thread (serial)
#0 0x00007fff9285e132 in psynch_cvwait ()
#1 0x00007fff86813ea0 in _pthread_cond_wait ()
#2 0x00007fff8ac257ae in -__NSOperationInternal _waitUntilFinished:
#3 0x00007fff8ac4a119 in -NSOperationQueue addOperations:waitUntilFinished:
#4 0x000000010001aab3 in -[UbiquityStoreManager enqueue:waitUntilFinished:lock:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:622
#5 0x000000010001d957 in -[UbiquityStoreManager fireBeginLoadingLogReason:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:917
#6 0x000000010002f947 in -[UbiquityStoreManager storesWillChange:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:2199
#7 0x00007fff849cccbc in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER
()
#8 0x00007fff848be1b4 in _CFXNotificationPost ()
#9 0x00007fff8abbaea1 in -NSNotificationCenter postNotificationName:object:userInfo:
#10 0x00007fff8f52cc6d in __81-[PFUbiquitySetupAssistant tryToReplaceLocalStore:withStoreSideLoadedByImporter:]_block_invoke ()
#11 0x0000000100384d43 in _dispatch_client_callout ()
#12 0x0000000100395589 in _dispatch_barrier_sync_f_slow_invoke ()
#13 0x0000000100384d43 in _dispatch_client_callout ()
#14 0x0000000100393d9f in _dispatch_main_queue_callback_4CF ()
#15 0x00007fff84963c59 in CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE ()
#16 0x00007fff849202ef in CFRunLoopRun ()
#17 0x00007fff8491f838 in CFRunLoopRunSpecific ()
#18 0x00007fff904e743f in RunCurrentEventLoopInMode ()
#19 0x00007fff904e71ba in ReceiveNextEventCommon ()
#20 0x00007fff904e6ffb in _BlockUntilNextEventMatchingListInModeWithFilter ()
#21 0x00007fff886b76d1 in _DPSNextEvent ()
#22 0x00007fff886b6e80 in -NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:
#23 0x00007fff886aae23 in -NSApplication run
#24 0x00007fff886962d4 in NSApplicationMain ()
#25 0x0000000100001972 in main at /Users/freiburg/Private/Development/Source Controlled/Diabetes Logbook NG/Diabetes Logbook NG/main.m:13
#26 0x00007fff928695c9 in start ()
Thread 2Queue : UbiquityStoreManagerPersistenceQueue :: NSOperation 0x608000449180 (QOS: USER_INITIATED) (serial)
#0 0x00007fff9285956a in semaphore_wait_trap ()
#1 0x00007fff8fe79c5b in _os_semaphore_wait ()
#2 0x0000000100390692 in _dispatch_barrier_sync_f_slow ()
#3 0x00007fff8f3b6946 in -NSManagedObjectContext performBlockAndWait:
#4 0x000000010000ea37 in -[DLAppDelegate ubiquityStoreManager:willLoadStoreIsCloud:] at /Users/freiburg/Private/Development/Source Controlled/Diabetes Logbook NG/Diabetes Logbook NG/DLAppDelegate.m:1268
#5 0x000000010001da7d in -[UbiquityStoreManager fireBeginLoadingLogReason:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:923
#6 0x000000010001dbaa in __50-[UbiquityStoreManager fireBeginLoadingLogReason:]_block_invoke at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:917
#7 0x000000010001ac0d in __55-[UbiquityStoreManager enqueue:waitUntilFinished:lock:]_block_invoke at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:627
#8 0x00007fff8acf52e8 in __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK
()
#9 0x00007fff8abe1905 in -NSBlockOperation main
#10 0x00007fff8abc059c in -__NSOperationInternal _start:
#11 0x00007fff8abc01a3 in NSOQSchedule_f ()
#12 0x0000000100384d43 in _dispatch_client_callout ()
#13 0x0000000100388fb3 in _dispatch_queue_drain ()
#14 0x000000010038afc0 in _dispatch_queue_invoke ()
#15 0x0000000100387f5e in _dispatch_root_queue_drain ()
#16 0x0000000100399cd0 in _dispatch_worker_thread3 ()
#17 0x00007fff868136cb in _pthread_wqthread ()
#18 0x00007fff868114a1 in start_wqthread ()
Enqueued from com.apple.main-thread (Thread 1)Queue : com.apple.main-thread (serial)
#0 0x0000000100386c92 in _dispatch_barrier_async_f_slow ()
#1 0x00007fff8abc0051 in __NSOQSchedule ()
#2 0x00007fff8abbf69e in __addOperations ()
#3 0x00007fff8ac4a08a in -NSOperationQueue addOperations:waitUntilFinished:
#4 0x000000010001aab3 in -[UbiquityStoreManager enqueue:waitUntilFinished:lock:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:622
#5 0x000000010001d957 in -[UbiquityStoreManager fireBeginLoadingLogReason:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:917
#6 0x000000010002f947 in -[UbiquityStoreManager storesWillChange:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:2199
#7 0x00007fff849cccbc in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER
()
#8 0x00007fff848be1b4 in _CFXNotificationPost ()
#9 0x00007fff8abbaea1 in -NSNotificationCenter postNotificationName:object:userInfo:
#10 0x00007fff8f52cc6d in __81-[PFUbiquitySetupAssistant tryToReplaceLocalStore:withStoreSideLoadedByImporter:]_block_invoke ()
#11 0x0000000100384d43 in _dispatch_client_callout ()
#12 0x0000000100395589 in _dispatch_barrier_sync_f_slow_invoke ()
#13 0x0000000100384d43 in dispatch_client_callout ()
#14 0x0000000100393d9f in dispatch_main_queue_callback_4CF ()
#15 0x00007fff84963c59 in CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE ()
#16 0x00007fff849202ef in CFRunLoopRun ()
#17 0x00007fff8491f838 in CFRunLoopRunSpecific ()
#18 0x00007fff904e743f in RunCurrentEventLoopInMode ()
#19 0x00007fff904e71ba in ReceiveNextEventCommon ()
#20 0x00007fff904e6ffb in _BlockUntilNextEventMatchingListInModeWithFilter ()
#21 0x00007fff886b76d1 in _DPSNextEvent ()
#22 0x00007fff886b6e80 in -NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:
#23 0x00007fff886aae23 in -NSApplication run
#24 0x00007fff886962d4 in NSApplicationMain ()
#25 0x0000000100001972 in main at /Users/freiburg/Private/Development/Source Controlled/Diabetes Logbook NG/Diabetes Logbook NG/main.m:13
#26 0x00007fff928695c9 in start ()
Thread 3Queue : com.apple.libdispatch-manager (serial)
#0 0x00007fff9285f22e in kevent64 ()
#1 0x000000010038871f in _dispatch_mgr_invoke ()
#2 0x00000001003883fc in _dispatch_mgr_thread ()
Thread 4#0 0x00007fff9285e946 in __workq_kernreturn ()
#1 0x00007fff86813757 in _pthread_wqthread ()
#2 0x00007fff868114a1 in start_wqthread ()
Thread 5#0 0x00007fff9285e946 in __workq_kernreturn ()
#1 0x00007fff86813757 in _pthread_wqthread ()
#2 0x00007fff868114a1 in start_wqthread ()
Thread 6Queue : com.apple.coredata.ubiquity.entry.pq (serial)
#0 0x00007fff9285956a in semaphore_wait_trap ()
#1 0x00007fff8fe79c5b in _os_semaphore_wait ()
#2 0x0000000100390692 in _dispatch_barrier_sync_f_slow ()
#3 0x00007fff8f52c691 in -PFUbiquitySetupAssistant tryToReplaceLocalStore:withStoreSideLoadedByImporter:
#4 0x00007fff8f528ced in -PFUbiquitySetupAssistant sideLoadStore:error:
#5 0x00007fff8f51eb16 in -PFUbiquitySetupAssistant finishSetupForStore:error:
#6 0x00007fff8f51dc60 in -PFUbiquitySetupAssistant finishSetupWithRetry:
#7 0x00007fff8f4e168e in __57-[PFUbiquitySwitchboardEntry executeBlockOnPrivateQueue:]_block_invoke ()
#8 0x000000010038a2bb in _dispatch_call_block_and_release ()
#9 0x0000000100384d43 in _dispatch_client_callout ()
#10 0x0000000100388fb3 in _dispatch_queue_drain ()
#11 0x000000010038afc0 in _dispatch_queue_invoke ()
#12 0x0000000100387f5e in _dispatch_root_queue_drain ()
#13 0x0000000100399cd0 in _dispatch_worker_thread3 ()
#14 0x00007fff868136cb in _pthread_wqthread ()
#15 0x00007fff868114a1 in start_wqthread ()
Enqueued from NSPersistentStoreCoordinator 0x608000469040 (Thread 5)Queue : NSPersistentStoreCoordinator 0x608000469040 (serial)
#0 0x00000001003981bb in _dispatch_barrier_async_f ()
#1 0x00007fff8f4e163b in -PFUbiquitySwitchboardEntry executeBlockOnPrivateQueue:
#2 0x00007fff8f4e151e in -PFUbiquitySwitchboardEntry finishSetupForStore:withSetupAssistant:synchronously:error:finishBlock:
#3 0x00007fff8f51d34a in -PFUbiquitySetupAssistant performCoordinatorPostStoreSetup:error:
#4 0x00007fff8f42068a in __91-[NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:]_block_invoke ()
#5 0x00007fff8f42fb3b in gutsOfBlockToNSPersistentStoreCoordinatorPerform ()
#6 0x0000000100384d43 in _dispatch_client_callout ()
#7 0x00000001003860b1 in _dispatch_barrier_sync_f_invoke ()
#8 0x00007fff8f41eb32 in _perform ()
#9 0x00007fff8f35e9fb in -NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:
#10 0x000000010002022c in -[UbiquityStoreManager loadStoreAtURL:withOptions:migratingStoreAtURL:withOptions:usingStrategy:cause:context:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:1073
#11 0x000000010001c9a0 in -[UbiquityStoreManager tryLoadCloudStore] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:811
#12 0x000000010001bea3 in -[UbiquityStoreManager reloadStore] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:744
#13 0x000000010001bf36 in __35-[UbiquityStoreManager reloadStore]_block_invoke at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:721
#14 0x000000010001ac0d in __55-[UbiquityStoreManager enqueue:waitUntilFinished:lock:]_block_invoke at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:627
#15 0x00007fff8acf52e8 in __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK
()
#16 0x00007fff8abe1905 in -NSBlockOperation main
#17 0x00007fff8abc059c in -__NSOperationInternal _start:
#18 0x00007fff8abc01a3 in NSOQSchedule_f ()
#19 0x0000000100384d43 in _dispatch_client_callout ()
#20 0x0000000100388fb3 in _dispatch_queue_drain ()
#21 0x000000010038afc0 in _dispatch_queue_invoke ()
#22 0x0000000100387f5e in _dispatch_root_queue_drain ()
#23 0x0000000100399cd0 in _dispatch_worker_thread3 ()
#24 0x00007fff868136cb in _pthread_wqthread ()
#25 0x00007fff868114a1 in start_wqthread ()
Enqueued from com.apple.main-thread (Thread 1)Queue : com.apple.main-thread (serial)
#0 0x0000000100386c92 in _dispatch_barrier_async_f_slow ()
#1 0x00007fff8abc0051 in __NSOQSchedule ()
#2 0x00007fff8abbf69e in __addOperations ()
#3 0x00007fff8ac4a08a in -NSOperationQueue addOperations:waitUntilFinished:
#4 0x000000010001aab3 in -[UbiquityStoreManager enqueue:waitUntilFinished:lock:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:622
#5 0x000000010001a90d in -[UbiquityStoreManager enqueue:waitUntilFinished:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:617
#6 0x000000010001a884 in -[UbiquityStoreManager enqueue:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:612
#7 0x000000010001a7e7 in -[UbiquityStoreManager ensureQueued:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:606
#8 0x000000010001bbd3 in -[UbiquityStoreManager reloadStore] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:721
#9 0x00000001000173aa in -[UbiquityStoreManager initStoreNamed:withManagedObjectModel:localStoreURL:containerIdentifier:storeConfiguration:storeOptions:delegate:] at /Users/freiburg/Private/Development/Source Controlled/UbiquityStoreManager/UbiquityStoreManager/UbiquityStoreManager.m:237
#10 0x00000001000045af in -[DLAppDelegate applicationDidFinishLaunching:] at /Users/freiburg/Private/Development/Source Controlled/Diabetes Logbook NG/Diabetes Logbook NG/DLAppDelegate.m:129
#11 0x00007fff849cccbc in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER
()
#12 0x00007fff848be1b4 in CFXNotificationPost ()
#13 0x00007fff8abbaea1 in -NSNotificationCenter postNotificationName:object:userInfo:
#14 0x00007fff886bf10b in -NSApplication _postDidFinishNotification
#15 0x00007fff886bee76 in -NSApplication _sendFinishLaunchingNotification
#16 0x00007fff886bbc76 in -NSApplication(NSAppleEventHandling) _handleAEOpenEvent:
#17 0x00007fff886bb6b5 in -NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:
#18 0x00007fff8abda458 in -NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:
#19 0x00007fff8abda2c9 in NSAppleEventManagerGenericHandler ()
#20 0x00007fff8421899c in aeDispatchAppleEvent(AEDesc const
, AEDesc
, unsigned int, unsigned char
) ()
#21 0x00007fff84218719 in dispatchEventAndSendReply(AEDesc const
, AEDesc*) ()
#22 0x00007fff84218623 in aeProcessAppleEvent ()
#23 0x00007fff904f437e in AEProcessAppleEvent ()
#24 0x00007fff886b7d76 in _DPSNextEvent ()
#25 0x00007fff886b6e80 in -NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:
#26 0x00007fff886aae23 in -NSApplication run
#27 0x00007fff886962d4 in NSApplicationMain ()
#28 0x0000000100001972 in main at /Users/freiburg/Private/Development/Source Controlled/Diabetes Logbook NG/Diabetes Logbook NG/main.m:13
#29 0x00007fff928695c9 in start ()
Thread 8#0 0x00007fff9285952e in mach_msg_trap ()
#1 0x00007fff9285869f in mach_msg ()
#2 0x00007fff84920b14 in __CFRunLoopServiceMachPort ()
#3 0x00007fff8491ffdb in __CFRunLoopRun ()
#4 0x00007fff8491f838 in CFRunLoopRunSpecific ()
#5 0x00007fff8881a7a7 in _NSEventThread ()
#6 0x00007fff868132fc in _pthread_body ()
#7 0x00007fff86813279 in _pthread_start ()
#8 0x00007fff868114b1 in thread_start ()
Thread 9#0 0x00007fff9285e946 in __workq_kernreturn ()
#1 0x00007fff86813757 in _pthread_wqthread ()
#2 0x00007fff868114a1 in start_wqthread ()
Thread 11#0 0x00007fff9285e946 in __workq_kernreturn ()
#1 0x00007fff86813757 in _pthread_wqthread ()
#2 0x00007fff868114a1 in start_wqthread ()

threads

@lhunath
Copy link
Owner

lhunath commented Jan 21, 2015

Apparently, iOS has now started to import changes into the store on the main thread: tryToReplaceLocalStore:withStoreSideLoadedByImporter:.

As a result, the main thread is busy importing changes when USM tells you to shut down your Managed Object Context. Unfortunately, your MOC is a main-thread MOC and needs to do work on the main thread in order to shut down.

This is an annoying situation, we should probably really be shutting down your main MOC before allowing the importer to start importing data into the store. Unfortunately, the main MOC has no opportunity to perform its block of work as the main thread is busy waiting for USM's persistence queue to shut down which is waiting for your main MOC to shut down.

Making fireBeginLoadingLogReason: not wait will cause the importer's notification to end before the main MOC has finished shutting down. As a result, the importer will detach your store from your persistence coordinator and if your main MOC has unsaved changes it needs to commit to the store, it will either fail or crash your app when it does its shutdown work asynchronously later on.

I don't understand why iOS is trying to replace the local store from the main thread. That's very annoying. Essentially, the correct fix would be for USM's willLoadStore: to be fired on whatever thread the notification is coming in on. Then performing a cleanup block on your main MOC will just run it in the current thread. Unfortunately, that would mean the contract of USM's willLoadStore: changes, and any safe operations done there involving USM's stores (such as store migration) need now be explicitly scheduled on USM's persistence queue somehow to avoid them happening while USM is using or changing the store from underneath them.

@pascalfribi
Copy link

that sounds interesting.

So in the end my proposed fix seems to be the only viable way to go forward. And people should then not do operations on the usm in the delegate for willLoadStore. Is this a meaningful thing to do in this notification anyway? I basically just use it to store unstored elements and reset the gui.

What is you proposal now?

Am 21.01.2015 um 23:01 schrieb Maarten Billemont [email protected]:

Apparently, iOS has now started to import changes into the store on the main thread: tryToReplaceLocalStore:withStoreSideLoadedByImporter:.

As a result, the main thread is busy importing changes when USM tells you to shut down your Managed Object Context. Unfortunately, your MOC is a main-thread MOC and needs to do work on the main thread in order to shut down.

This is an annoying situation, we should probably really be shutting down your main MOC before allowing the importer to start importing data into the store. Unfortunately, the main MOC has no opportunity to perform its block of work as the main thread is busy waiting for USM's persistence queue to shut down which is waiting for your main MOC to shut down.

Making fireBeginLoadingLogReason: not wait will cause the importer's notification to end before the main MOC has finished shutting down. As a result, the importer will detach your store from your persistence coordinator and if your main MOC has unsaved changes it needs to commit to the store, it will either fail or crash your app.

I don't understand why iOS is trying to replace the local store from the main thread. That's very annoying. Essentially, the correct fix would be for USM's willLoadStore: to be fired on whatever thread the notification is coming in on. Then performing a cleanup block on your main MOC will just run it in the current thread. Unfortunately, that would mean the contract of USM's willLoadStore: changes, and any safe operations done there involving USM's stores (such as store migration) need now be explicitly scheduled on USM's persistence queue somehow to avoid them happening while USM is using or changing the store from underneath them.


Reply to this email directly or view it on GitHub.

@lhunath
Copy link
Owner

lhunath commented Jan 23, 2015

No, your proposed fix seems like it will break your app.

And people should then not do operations on the usm in the delegate for willLoadStore.

People need to be able to do store migration in willLoadStore, such as when a new version of their app requires work on the user's old store before loading it. Eg. moving the store, upgrading entities, importing things, etc.

I basically just use it to store unstored elements and reset the gui.

And, as I said, if you do this using your proposed fix, you're likely to destroy your unstored elements or crash your app due to unsatisfiable faults or the fact that you're saving without a backing store attached to your persistence coordinator. I can't promise you it'll crash, since that's dependant on what iOS' import does exactly and the timing of things, so you may not be able to reproduce the crash easily, but I promise you the flow is broken.

What is you proposal now?

As I said, never schedule willLoadStore: on the persistence queue (fire it synchronously from the notification handler) and note in the documentation that there is no guarantee that it is running on any particular thread, meaning that all store operations it does need to be separately scheduled on the persistence queue. Alternatively, we could leave willLoadStore: as is and add a separate delegate that is either cleanUpYourMOCs: or gimmeYourMOCsSoICanCleanThemUpForYou: which would get fired before willLoadStore: to save and reset your MOCs for you in a manner synchronous with the notification.

@pascalfribi
Copy link

Hi,

I think we should look for a clean solution within your library itself. At the moment the situation is, that willLoadStore is called from the persistenceQueue out of your code. Now if we would call this from any thread where the notification comes in then this breaks your pattern. And I cannot make operations on the persistentStorageQueue out of my delegate as I do not have access to this queue outside your code. Furthermore this is also not a very clean way to make this accessible from outside your code.

So a delegate like cleanUpYourMOCs: would make perfect sense.

By the way: the fix I proposed (meaning just call it from the queue the notification comes in) is the only way I can keep my app from either deadlocking or crashing without adding an additional delegate. I need to clean up this MOC before it gets destroyed. So I need to do this blocking and on the Main queue (as it is a NSMainQueueConcurrencyType moc).

Up to you what we should do :-)

Pascal

On 23 Jan 2015, at 13:24, Maarten Billemont [email protected] wrote:

No, your proposed fix seems like it will break your app.

And people should then not do operations on the usm in the delegate for willLoadStore.

People need to be able to do store migration in willLoadStore, such as when a new version of their app requires work on the user's old store before loading it. Eg. moving the store, upgrading entities, importing things, etc.

I basically just use it to store unstored elements and reset the gui.

And, as I said, if you do this using your proposed fix, you're likely to destroy your unstored elements or crash your app due to unsatisfiable faults or the fact that you're saving without a backing store attached to your persistence coordinator. I can't promise you it'll crash, since that's dependant on what iOS' import does exactly and the timing of things, so you may not be able to reproduce the crash easily, but I promise you the flow is broken.

What is you proposal now?

As I said, never schedule willLoadStore: on the persistence queue (fire it synchronously from the notification handler) and note in the documentation that there is no guarantee that it is running on any particular thread, meaning that all store operations it does need to be separately scheduled on the persistence queue. Alternatively, we could leave willLoadStore: as is and add a separate delegate that is either cleanUpYourMOCs: or gimmeYourMOCsSoICanCleanThemUpForYou: which would get fired before willLoadStore: to save and reset your MOCs for you in a manner synchronous with the notification.


Reply to this email directly or view it on GitHub #73 (comment).

@lhunath
Copy link
Owner

lhunath commented Jan 23, 2015

Until a good solution is in place, a work-around would be for you to register for the notification (preferably before you initialize USM) and in your own notification handler clean up and nil your MOC.

@pascalfribi
Copy link

I can’t do that. The problem happens in initializing Cloud stores when it changes from use local:1 to use local: 0. At this time I have already initialized and used USM.

On 23 Jan 2015, at 13:47, Maarten Billemont [email protected] wrote:

Until a good solution is in place, a work-around would be for you to register for the notification (preferably before you initialize USM) and in your own notification handler clean up and nil your MOC.


Reply to this email directly or view it on GitHub #73 (comment).

@lhunath
Copy link
Owner

lhunath commented Jan 23, 2015

You would register the notification before you init the USM object. Your registration handler will then get called before your willLoadStore:, ie. before the problem happens.

@pascalfribi
Copy link

The notification is sent multiple times when iCloud is active. First time, when I set up the MOC with USM, second time when Core Data switches from the local to the cloud store.

On 23 Jan 2015, at 13:54, Maarten Billemont [email protected] wrote:

You would register the notification before you init USM. Your registration handler will then get called before your willLoadStore:, ie. before the problem happens.


Reply to this email directly or view it on GitHub #73 (comment).

@lhunath
Copy link
Owner

lhunath commented Jan 23, 2015

... and each time NSPersistentStoreCoordinatorStoresWillChangeNotification is fired, your MOCs need to be torn down. They will come back up after NSPersistentStoreCoordinatorStoresDidChangeNotification which triggers didLoadStoreForCoordinator:. Really, I'm not interested in micro-managing. Either figure out how you register for the notification or override USM's storesWillChange: in a subclass and shut down your MOCs before the super call. Or fork and fix USM.

@pascalfribi
Copy link

No need to be offended.

I know how to call the notifications and how to do this. You are also insisting to have a proper solution in your USM without hacks, so do I :-)

Subclassing your code or calling the notification myself is a hack in my opinion. And I want others to profit from the change as well and right in your USM code.

Would you accept a pull request where I add a delegate like cleanUpYourMOCs (maybe a better name), which is called before triggering willLoadStore: out of the persistentStorageQueue? If yes, then I will fork your code implement it and make a pull request.

I accept all answers. It’s your code and I like it and I am glad it exists.

On 23 Jan 2015, at 15:42, Maarten Billemont [email protected] wrote:

... and each time NSPersistentStoreCoordinatorStoresWillChangeNotification is fired, your MOCs need to be torn down. They will come back up after NSPersistentStoreCoordinatorStoresDidChangeNotification which triggers didLoadStoreForCoordinator:. Really, I'm not interested in micro-managing. Either figure out how you register for the notification or override USM's storesWillChange: in a subclass and shut down your MOCs before the super call. Or fork and fix USM.


Reply to this email directly or view it on GitHub #73 (comment).

@nandpal
Copy link

nandpal commented Sep 28, 2015

Hi lhunath,

Can you please tell me how to merge local data with iCloud data and vise versa when user turn On/Off iCloud switch.

Currently when i am turning on iCloud switch it display cloud data and when i am turning off iCloud switch it display local data. I need to merge my data when turning off to on(Local to iCloud & iCloud to Local).

Regards,
Nandpal

@lhunath
Copy link
Owner

lhunath commented Sep 28, 2015

USM never does any merging of stores automatically. If you want this you will need to manually invoke one of USM's utility methods for this. (eg. -migrateCloudToLocal and -migrateLocalToCloud). Please just read through UbiquityStoreManager.h. All is well explained.

@nandpal
Copy link

nandpal commented Sep 29, 2015

Thanks for quick reply.

I will use those two methods.
On 28 Sep 2015 21:41, "Maarten Billemont" [email protected] wrote:

USM never does any merging of stores automatically. If you want this you
will need to manually invoke one of USM's utility methods for this. (eg.
-migrateCloudToLocal and -migrateLocalToCloud). Please just read through
UbiquityStoreManager.h. All is well explained.


Reply to this email directly or view it on GitHub
#73 (comment)
.

@nandpal
Copy link

nandpal commented Sep 30, 2015

Hi lhunath,

Can you please help for resolve below scenario.

  • Enable iCloud account using device settings in my iPhone and iPad.
  • 1st install application in iPhone.
  • Enter 1 entry like "11" while i was online in iCloud.
  • Install application in iPad at that time got 1 entry "111" from iCloud which was already entered through iPhone.
  • Enter 1 entry "222" in my iPad so total number of entries count become two.
  • Got 1 entry "222" in iPhone which was entered through my iPad.
  • At this stage total number of entries "111", "222" become a two in both the devices.
  • Turn off iCloud account in both the devices and enter 1 entry in both the devices at that time total number of entries become three in both the devices. (iPhone entry - “333”, iPad entry - “444”)
  • Now Turn on iCloud in both the devices and migrate Cloud data with Local data using "migrateLocalToCloud” method and got the main problem, I was lose 1 entry “333” which i was entered through my iPhone.

Please check below final result off entries.

Final Result :

Abc
PQR
444

Regards,
Nandpal

@lhunath
Copy link
Owner

lhunath commented Sep 30, 2015

That is exactly what is expected. Please read what -migrateLocalToCloud does.

@nandpal
Copy link

nandpal commented Sep 30, 2015

Okay lhunath.

Can you please give me idea what i will do for resolve my problem, The main problem is when i am entered data offline mode in both device and again online iCloud.

i want all the data like without losing "333" entry
Abc
PQR
333
444

Rest of the things works fine in my app only above scenario creates the main problem.

  • Nandpal

@lhunath
Copy link
Owner

lhunath commented Sep 30, 2015

You cannot do that. There is no sane way to merge two disjoint local data sets.

If you want to brave it anyway, despite not realizing the massive scope of the problem you are asking to solve, please do it yourself, manually. USM cannot do this for you.

@nandpal
Copy link

nandpal commented Oct 2, 2015

Hi lhunath,

Thanks for response also appreciate for great library.

  • Nandpal

@nandpal
Copy link

nandpal commented Jan 15, 2016

Hello All,

I am getting below response while i was try to sync data.


failed to receive initial sync notification call back in 90 seconds

CoreData: iCloud: Error: failed to receive initial sync notification call back in 90 seconds
2016-01-15 15:42:45.326 What I Did[557:15395] -[PFUbiquitySetupAssistant


Blocking for initial sync

canReadFromUbiquityRootLocation:](1404): CoreData: Ubiquity: Blocking for initial sync: <PFUbiquitySetupAssistant: 0x14ee8da30>

Can any one help for resolve this issues.

Thanks

@sw-tt-jethanandnandpal
Copy link

Hi,

I was added some data in iPad with current date "25 April 2017" its create a new cloud container in my iCloud account. After that i was trying to download entered data in iPhone 6+ that time the app was stuck, i was tried to figured out the issue the issue was having with iPhone date. in my iPhone is configured with past date "15 April 2017". I was again try with same date "25 April 2017" its working fine, But if i set past or future date i was suffered from above issue.

Can any one help for resolve this issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests