and did not receive a callback for approximately 15 minutes of the entire app session.
What callback are you referring to here? providerDidBegin(_:)?
Jumping back to what I said here:
Yes, it looks like there is a bug there. More specifically, calling CXProvider.init(configuration:) kicks off an XPC connection to callservicesd on a secondary thread, the end of which eventually calls providerDidBegin(_:). If that completes before you're able to call setDelegate, then you'll see the problem you're describing.
The problem that's actually happening here is that the system actually DID try to call "providerDidBegin()", but was unable to do so because the delegate had not been set "yet". In other words, there is an inherent race condition between:
- The backend logic which "CXProvider.init(configuration:)" kicks off completing (which is what triggers "providerDidBegin()").
AND
- Your app calling CXProvider.setDelegate() so that the system CAN call your "providerDidBegin()".
If #1 completes before #2, then providerDidBegin() will never be called. One obvious note on all this- the FIRST thing your app should do after calling CXProvider.init(configuration:) is call CXProvider.setDelegate(). Any work that occurs between those two points will greatly increase the likelihood of failure.
so does really initialising PushKit on a secondary queue is the primary concern for this issue?
To be clear, my comment about PushKit and threading was entirely speculative. I don't know what's actually causing the race to occur, but I do suspect that some amount of thread complexity is required. Putting that another way, I don't think a single threaded app that did this on the main thread could trigger hit the race condition above:
... CXProvider.init(configuration:)
... CXProvider.setDelegate(...)
That's not because it actually eliminates the race condition (it doesn't), but is because the combination of:
...would make it VERY hard for #1 to finish "first".
However, ALL of this isn't really the solution. The actual solution here is:
Expanding on what I said earlier, I think the simplest answer here is to simply ignore providerDidBegin and treat the CXProvider as fully functional from the moment it's created.
Expanding on that, there isn't really any reason for your app to delay anything based on providerDidBegin. Just start using the provider and everything will work fine.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware