While working on my zentangles app, I added a spinner that appears when the app is fetching or saving data to CloudKit. This appeared to be working wonderfully. But then I tried using the app when I didn’t have access to the network. The spinner appeared and never disappeared.
Not Good!
I immediately thought of a couple of things that might fix the problem. Things like setting the time out for the network operation, using the Reachability frame work to detect when there was no network. But when I attempted to set the CKOperation’s time out, Xcode told me I was using a deprecated function, and I should really be using CKOperationConfiguration. Groan! I thought. This new things is likely just helping some obscure use case that doesn’t apply to me.
Sure enough CKOperationConfiguration has a timeout interval property, to let me do what I thought I needed to do. But then I noticed another property called qualityOfService that can have one of the following values: background, utility, default, userInitiated, userInteractive. Hmm, the header describes the behaviour for these different values…
As an aside, I find myself a bit confused on the subject of timeout intervals. It appears the operation’s configuration has a default timeout of 60 seconds. When I run in a simulator and disable networking on my computer, it appears to time out after 10 seconds When I run on an iPad, not on any networks, it appears to never time out. <Shrug Emoji>
Regardless of timeout confusion QualityOfService is a much smarter way to describe a network operation. When I set QualityOfService to UserInteractive and then attempted a fetch on a device with no network, the operation immediately failed. (likely thanks to internally using Reachability?) Awesome!
I do still have a couple of questions about Quality of Service.
Are there any behaviour differences between UserInteractive and UserInitiated? From the table above, they appear to be identical, but the devil may be in the details.
Is there a way to create a hybrid approach? ie can I get a result right away that will make my spinner go away, but still do retries? Perhaps I don’t really need a spinner on a network operation that is just sending updates to the server….