Archive for November 7, 2024

Thursday, November 7, 2024

CloudKit Reference and Index Issues

Kuba Suder:

CloudKit also automatically creates indexes for each field in each record type - when you’re done with development, you can delete some indexes that you won’t need so they don’t waste space in the production database.

Apple:

A request to fetch records performs a query on indexed fields for a particular record type. At least one field in the record needs to be indexed to perform an empty query that fetches all records. Because indexes are updated asynchronously, they are not guaranteed to be current.

Eric Zinda:

The solution is to use CKFetchRecordChangesOperation, if the data is in a custom zone of the private database. If you are using the public database, or the default zone of the private database, think about this:

  1. The device making the changes knows the changes. [meaning: keep a cache of the updates you make]
  2. The other peer devices observe the changes using CKQuerySubscription.

Jaanus Kase:

This is one of those posts, exploring how querying based on CKReference works, and what are the limits and behaviors of that.

[…]

Here is one important bit: you can’t do queries by parent property. I couldn’t immediately find the authoritative source for this in the SDK documentation, but the recommendation in Apple forums and elsewhere has always been to add your own CKReference fields if you want to query by parent record.

[…]

The key bit is the predicate for the reference set. I got the idea for setting up this way from this StackOverflow post. The official CloudKit documentation does have examples for querying based on references, but not reference sets and more complex scenarios.

[…]

Fair enough. This tells me that the filtering condition in the clause ANY %@ in relatedRecords can’t contain more than 250 objects. So, let’s limit it, leave some headroom, and run it with 200 records instead.

[…]

Even though the input contains only 200 objects, I get this error. I speculate that even though the input amount is below the nominal stated limit, some relationship query to construct the results causes some internal limit overflow on the CloudKit side, and it doesn’t handle this situation well.

Casey Liss:

Thinking about this some more, and in chatting with the good samaritans on Slack, we all came to the same conclusion: the index probably didn’t properly… uh… index… whatever data was already there before the index was created.

So, if you’re ever in a situation where you’re getting wonky results (or no results at all) from a new field in CloudKit, consider whether the data you’ve added was done so before or after you added the corresponding index.

Previously:

Problematic Swift Concurrency Patterns

Matt Massicotte:

I think the vast majority of the time, a global actor should be applied to the type as a whole, not to individual properties.

[…]

But, while detached does prevent isolation inheritance, it also does other stuff too. Detached tasks do not inherit priority or task-local values. Instead, think about a nonisolated function.

[…]

I think MainActor.run is rarely the right solution.

[…]

Moving from completion handlers to async methods can change semantics and cause code to run on background threads. Be really careful here!

[…]

The compiler will automatically generate async versions of Objective-C completion handler-based methods. The bad news is, unless the type itself is MainActor-isolated or Sendable, these translations will be problematic. They won’t be possible to use diagnostic-free without a @preconcurrency import and will have different semantics that could make them unsafe.

Previously:

iOS 18: Health App Medications

Joe Rosensteel:

It doesn’t list interactions for things that are not in the medication app, like vitamin supplements, antacids, NSAID painkillers, etc. All of which had very clear, urgent warnings in the prescription paperwork, but because they aren’t the two medications in the app there’s no warning.

[…]

Despite being able to OCR the prescription info, there’s nothing to OCR the side effects info and log that.

[…]

I needed to take it once a day but the number of pills started high and tapered off twice over the following days. The app lets you put in a dosage to schedule, but I couldn’t find any way to vary it over time.

[…]

This was also a drug that should be taken with food, but there’s not a “hey, eat something” notification you can configure to come up before it’s time to take the drug. The antibiotic should really not be taken at a time anywhere near when you’re going to eat certain things, or even have most vitamin supplements, so I also have to mentally track when I do those things too.

Another quirk is that the notification to take your medications comes through on the Watch without mention of which medication you need to take[…] It’s also always plural, even if you’re only taking one medication at 1:00 PM, which is confusing.

Previously:

iOS 18: Screen Sharing With Remote Control

Federico Viticci:

When you start observing another person’s screen in iOS 18, the system will tell you that you can now tap and draw on their screen. Taps are drawn as purple circles that disappear quickly – they’re subtle, but noticeable.

[…]

With the ability to control another person’s device, you literally take over their interactions until they interact with the device again (which can be a tap or even taking a screenshot on their end).

[…]

I was able to test remote control with John over FaceTime, and I noticed some interesting details in Apple’s implementation. I was able to open John’s Camera app, have him move the phone to look around his office, and remotely press the shutter button. I couldn’t, however, type in Spotlight search or see the Passwords app. When I opened it, I got a message telling me that I had to wait for John to proceed.

[…]

I look forward to fixing my mom’s Wi-Fi connection and updating her apps remotely thanks to the addition of remote control in FaceTime’s screen sharing.

Previously: