I ran into a problem recently with my production app and an update for iOS 18. In this example I was using a new API added to the RC candidate of iOS 18.0, using this API as an example, I couldn't find a satisfactory way to avoid crashing on iOS 18.1 where the API was not available. I had plenty of users running the iOS 18.1 Beta and ultimately it's my fault if a version of my app did work, and then didn't after an update....
This code causes a crash on iOS 18.1 beta as the .appleSleepingBreathingDisturbances API doesn't seem to have made it's way into the beta:
if #available(iOS 18.0, *), #available(watchOS 11, *) {
healthKitTypesToRead.insert(HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances)!)
}
I tried this but it still crashed on 18.1:
if #available(iOS 18.0, *), #available(watchOS 11, *) {
if let newQuantity = HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances) {
healthKitTypesToRead.insert(newQuantity)
}
}
In the end the only way I could resolve this was the following:
if #available(iOS 18.1, *){
// Do nothing
}
else if #available(iOS 18.0, *), #available(watchOS 11, *) {
if let newQuantity = HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances) {
healthKitTypesToRead.insert(newQuantity)
}
}
This seems like a poor solution and I'll have to ensure I release a new version of the app once iOS 18.1 has the available API added to enable support for the feature.
How could I have checked availability for this API correctly without causing the app to crash? I'm asking this question more as a Swift language feature rather than issue with the specific API as I'm sure that will get resolved soon anyway.
Thanks
How could I have checked availability for this API correctly without causing the app to crash?
I don’t think there’s a good answer here. Swift’s availability is predicated on the fact that APIs don’t disappear in later OS releases, but that’s exactly what happened here. Situations like this are exceedingly rare, so it’s hard to come up with a general solution to it. And honestly, I’m not sure it’s worth coming up with such a solution [1].
Did you file a bug about this specific missing API? Or did it already land in a later iOS 18.1 beta?
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] Back in the day we used a very different availability strategy, one based on checking for the symbol being nil
. That worked well in the more chaotic environment that was traditional Mac OS. However, it produced its own set of problems, and with Mac OS X’s more orderly approach to OS releases, the new model really does make more sense.