iosswiftmac-catalystavailability

Swift availability check for macCatalyst / iOS failing


I have added an iOS 15+/macCatalyst 15.0+ function to my app and now it is crashing when run on an M1 iMac through Mac Catalyst (Designed for iPad).

I have an availability check around my function however when run on my Mac (macOS 11.6), the code within the availability check still runs, and crashes.

if #available(iOS 15.0, macCatalyst 15.0, *) {
    dataSource.applySnapshotUsingReloadData(fullSnapshot, completion: nil)
} else {
    dataSource.apply(fullSnapshot, animatingDifferences: false)
}

I understand the Designed for iPad mac catalyst runs as iOS, and I can confirm it is running as iOS 14.7 using print(UIDevice.current.systemVersion) so why is it running code that is set to run on iOS 15+ only?

Am I doing my macCatalyst check right?


Solution

  • It turns out this is a known issue and actually mentioned in the Xcode 13 release notes.

    Availability checks in iPhone and iPad apps on a Mac with Apple silicon always return true. This causes iOS apps running in macOS 11 Big Sur to see iOS 15 APIs as available, resulting in crashes. This only affects apps available in the Mac App Store built with the “My Mac (Designed for iPhone)” or “My Mac (Designed for iPad)” run destination. It doesn’t affect Mac Catalyst apps. (83378814)

    Workaround: Use the following code to check for iOS 15 availability:

    if #available(iOS 15, *), ProcessInfo.processInfo.operatingSystemVersion.majorVersion >= 15 {