-
Notifications
You must be signed in to change notification settings - Fork 37
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
Comments
Hi @ChristianRo, Any progress on this one? |
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:
|
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/mobile |
@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. |
@NorbNorb I am facing the same dilemma as you. Have you found any solution to this or how you may proceed? |
You could try omitting the |
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. |
@lhunath: We're really facing huge problems due to this. Do you think you can give us a hand on this topic? |
The store does not sync without NSPersistentStoreUbiquitousContentURLKey? What is the error? |
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. |
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. |
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. |
I don't know anything at all about cloud drive or how it affects Core Data. |
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 So I tested to change it to performBlock instead of performBlockAndWait 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. |
@polarneo do you have a working iCloud sync with USM on iOS 8? |
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:
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. |
@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? |
My app also got stuck on iOS8. |
@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. |
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. |
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. |
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 :-) |
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. |
I will send you this this evening.
|
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:
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) |
Apparently, iOS has now started to import changes into the store on the main thread: 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 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 |
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?
|
No, your proposed fix seems like it will break your app.
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.
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.
As I said, never schedule |
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
|
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. |
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.
|
You would register the notification before you init the USM object. Your registration handler will then get called before your |
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.
|
... and each time |
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.
|
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, |
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. |
Thanks for quick reply. I will use those two methods.
|
Hi lhunath, Can you please help for resolve below scenario.
Please check below final result off entries.Final Result :Abc Regards, |
That is exactly what is expected. Please read what |
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 Rest of the things works fine in my app only above scenario creates the main problem.
|
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. |
Hi lhunath, Thanks for response also appreciate for great library.
|
Hello All, I am getting below response while i was try to sync data. failed to receive initial sync notification call back in 90 secondsCoreData: iCloud: Error: failed to receive initial sync notification call back in 90 seconds Blocking for initial synccanReadFromUbiquityRootLocation:](1404): CoreData: Ubiquity: Blocking for initial sync: <PFUbiquitySetupAssistant: 0x14ee8da30> Can any one help for resolve this issues. Thanks |
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. |
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:
kind regards,
Christian
The text was updated successfully, but these errors were encountered: