NSPersistentCloudKitContainer in Production
Asked Answered
W

2

8

I've recently released an app that uses NSPersistentCloudKitContainer. In development my database is synchronizing across devices as expected, but in production my database is not synchronizing at all. Once I debugged the situation, I realized I had to publish the iCloud Schema to production. But even after doing that, my app is not synchronizing across devices in production.

Has anyone experienced this? Is there something else I need to do for NSPersistentCloudKitContainer to work in production?

Wouldbe answered 3/10, 2019 at 12:12 Comment(3)
I have the same issue and I’m in the middle of a Technical Support Request with an Apple Engineer - so far, crickets.... but they’re looking into it. I had all the correct capabilities set, I made sure it was all working on my developer build, deployed the schema, and released my app. I’m the only person that’s seeing syncing occur - even with the App Store Version. It seems as though ‘normal’ users can’t actually create the private database/zone/whatever. Worse still, it’s corrupted some users’ local Core Data entities resulting in App launch crashes where ‘object ID is nil’ or something :(Provenience
I should expand on the above. If I delete my local Xcode built app, delete all the iCloud data for it, reboot my device and install the App Store version of my app from scratch on my devices, it syncs. It seems like it’s some sort of subscription issue that happens automatically when developing (and transfers to production) but fails for users who only run the app in the production environment. At the moment I’m putting out spot fires & fixing issues with my user... or at least trying to. I feel like it’s 99% there but these final hurdles are doing damage.Provenience
...and I have NO idea how to fix the Core Data ‘object ID is nil’ crashes that NSPersistentCloudKitContainer seemed to inject into my users’ CoreData objects. It’s a fatal error that I can’t catch or fix.Provenience
P
19

I think have worked out what’s going on as I was having the same problem, despite following all the steps in Apple’s Documentation for NSPersistentCloudKitContainer.

To make sure your Core Data entities are all created correctly in the Development Environment, before deploying to the Production Environment, they recommend running (once) the .shouldInitializeSchema on your NSPersistentCloudKitContainer.

Problem is, this hasn’t been valid for months (see more below...) so the other way to do it - and the way I did it - was to create all my data on-the-fly, saving to Core Data which created the schema in the Development Environment via NSPersistentCloudKitContainer. I then deployed it to Production when it was working perfectly on my devices.

While it was working perfectly well for my data, it wasn’t working for any of my users in the real world using my App Store version of the App. It was a real head-scratcher.

It turns out that there were a few missing Custom Fields in one or two Custom Types in the CloudKit Schema for my Core Data model - attributes which exist in my model but which I no longer use (one was just an empty string which I never use).

Problem is, NSPersistentCloudKitContainer doesn’t like this, even if an NSManagedObject has attributes you don’t use, they must be present in the CloudKit Schema for it to work. It seems to need a Custom Field to match each attribute in the Core Data model exactly.

Why it worked on my devices might be related to the fact that at some point in the past, these Custom Types and Custom Fields were all present in the Development Environment prior to a reset, by which stage my devices had everything in place already for them in iCloud.

The Custom Types (as seen in your CloudKit Dashboard) need to have Custom Fields that match every Core Data Attribute for the corresponding Entity as well as a Custom Field for each ‘to-one’ relationship (I had one of those missing too). They are all the fields that start with CD_ which are autogenerated by NSPersistentCloudKitContainer.

The ‘to-many’ relationships seemed to be stored elsewhere.

With Apple’s help, they suggested running the .shouldInitializeSchema replacement initializeCloudKitSchema(options:) (not yet in their documentation!) on the container (just once) to fill in all the gaps.

When I did this, I noticed it didn’t actually add any missing Custom Fields at all, and when I ‘Deployed to Production’ there were no changes to make and while it still worked on my devices, production devices weren’t working. On further analysis, the missing fields were NOT added...

So, instead, I made sure some data was written to my test device for all these missing attributes & ‘to-one’ relationships, then tried again.

I could see they were all now present in the Development Schema, which I deployed to production. All the missing Custom Types and Custom Fields were listed in the change.

It now all works for my users!

What a complicated process. Partly my fault, partly Apple’s.

Provenience answered 7/11, 2019 at 22:4 Comment(4)
I think this might have worked. I'm still testing though. Nice find.Wouldbe
"not yet in their documentation!" 🤬Ingraft
Amazing comment. Thank youHeritage
It's 2023 and I had a very similar issue. Development worked perfect while Production was giving me partialFailure on TestFlight devices. This answer triggered me to check the CloudKit schema for Production, and sure enough, it did not match. Doing another Deploy Schema Changes action from CloudKit console resolved my issue. That critical step should be double-checked.Photoelasticity
C
1

I had the same problem, in my case the problem was that I was only activating the capabilities in the "Debug" section, because it is the tab opened by default when selecting "Signing & Capabilities"

Double check that you are also activating the needed capabilities in the "Release" section.

enter image description here

Cardoon answered 26/10, 2019 at 15:4 Comment(1)
I have the same issue and this wasn’t the solution, sorry. I had all the correct capabilities set, I made sure it was all working on my developer build, deployed the schema, and released my app. I’m the only person that’s seeing syncing occur - even with the App Store Version. It seems as though ‘normal’ users can’t actually create the private database/zone/whateverProvenience

© 2022 - 2024 — McMap. All rights reserved.