[[UIDevice currentDevice] systemVersion] issue in iOS 26

We are testing our existing live build, which was prepared with Xcode 16.2, on iOS 26 beta for experience assurance and found that the [[UIDevice currentDevice] systemVersion] API is returning iOS 19 instead of the expected version iOS 26. Has anyone else observed this issue?

Answered by DTS Engineer in 846710022

I believe that this is working as designed. You get different results based on whether you’re building with iOS 26 beta SDK or not.

Consider this sequence:

  1. Using Xcode 16.4, I created a small test app that displays the system version.

  2. I used the organiser window to export an Ad Hoc signed version.

  3. I installed that .ipa on my iOS 26.0b2 (23A5276f) device. It shows the system version as 19.0.

  4. I then opened the very same project in Xcode 26.0b2.

  5. A chose Product > Run.

  6. The app shows the system version as 26.0.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I believe that this is working as designed. You get different results based on whether you’re building with iOS 26 beta SDK or not.

Consider this sequence:

  1. Using Xcode 16.4, I created a small test app that displays the system version.

  2. I used the organiser window to export an Ad Hoc signed version.

  3. I installed that .ipa on my iOS 26.0b2 (23A5276f) device. It shows the system version as 19.0.

  4. I then opened the very same project in Xcode 26.0b2.

  5. A chose Product > Run.

  6. The app shows the system version as 26.0.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Shouldn't it display the current operating system version? For instance, if I install the app on an iOS 26 beta device, this API should return iOS 26 rather than iOS 19, regardless of which Xcode version I used to build my app.

So it’s the same trick that was used in the jump from macOS 10.15 to 11.0, where legacy apps saw the new version as 10.16 instead of 11.0. But that was ostensibly to support old apps with faulty version checking logic that assumed the major part would be 10 forever and the minor part would increase forever.

But for the jump from OS 18 to 26 on the other platforms, it’s not clear why this would be needed. As happens every year on those platform, the major part still gets bigger and the minor part still gets reset to 0.

it’s not clear why this would be needed.

And that brings us into the why question territory, per tip 3 in Quinn’s Top Ten DevForums Tips.

OTOH, the how of this is fascinating. While researching this I found this bonne bouche in the Darwin open source.

WARNING Darwin source is, by definition, full of implementation details. Don’t encode those implementation details in your product.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

So it means this is intentional? We use this information to find out which iOS version the customer is using. In case they want to share iOS information to help debug any issue, showing iOS 19 to the customer instead of iOS 26 might confuse them.

And that brings us into the why question territory

And therefore unlike competing on the popular American quiz show Jeopardy!, I made sure not to phrase that response in the form of a question. 😉

OTOH, the how of this is fascinating.

Interesting! Of course if you multiply that by the number of “if your app is linked on or before version x...” cases scattered through the documentation, it’s probably not a lot of fun to maintain.

showing iOS 19 to the customer instead of iOS 26 might confuse them.

You could file a Feedback (and could cite my simple analysis above) but hopefully you have enough time to just prepare (at worst) a no-net-changes build of your app using Xcode 26. If you release that close to the iOS 26 release date then the confusion should be minimal. And for anyone who gets a confusing result running your old app on the beta, just chalk it up to ”well, it’s a beta.”

a no-net-changes build of your app using Xcode 26

That’s trickier than it seems because lots of other behaviour is gated behind a linked-on-or-later checks. So just rebuilding your app with Xcode 26 beta might raise all sorts of other issue.

Of course, you’re gonna need to fix those issue at some point anyway, so it’s not wasted work. But it might be more work than you have time for right now.

However, there is another short-term solution: Create this no-net-changes build with Xcode 16 and just special case the OS version.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

another short-term solution: Create this no-net-changes build with Xcode 16 and just special case the OS version.

Unfortunately that may not meet the OP’s requirement to report an accurate version for troubleshooting, since it sounds like the compatibility version will be stuck at 19.0 forever. So a compatibility-mode app can only infer it’s running on 26.0 or later but not determine the actual version. But hopefully that’s sufficient for the OP since it doesn’t sound like this drives any core app functionality.

[[UIDevice currentDevice] systemVersion] issue in iOS 26
 
 
Q