4

I would like to be able to somehow detect if my app is running on a beta version of macOS 11, as there are some known bugs I want to inform users about. I only want to show such an alert to macOS 11 beta users, meaning not macOS 10.15 users nor users on the final version of macOS 11. I could of course just submit an app update to remove the alert when macOS 11 is close to being done, but it would be nice to have something reusable I could use in multiple apps and for future macOS beta versions.

Constraints:

  • The app is sandboxed.
  • The app is in the App Store, so no private APIs.
  • The app doesn't have a network entitlement, so the detection needs to be offline.
  • I don't want to bundle a list of known macOS build numbers and compare that.

My thinking is that maybe it's possible to use some kind of sniffing. Maybe there are some APIs that return different results when the macOS version is a beta version.

6
  • 1
    If it's running macOS 11 isn't it, by definition, running the beta? Once the OS goes final, update your app. There's no "beta" flag that I know of, and there's no way to know what the final (release) version number will be without a crystal ball. Commented Jul 5, 2020 at 18:57
  • 3
    @JamesBucanek Your comment is already covered by the question text. Please read it. Commented Jul 7, 2020 at 18:21
  • Why checking random OS feature is better than hardcoding the version number? Checking the OS version is the common approach to such problems. Also, everyone is get used to nothing is working on macOS betas so maybe that's not a big of an issue. Commented Jul 8, 2020 at 7:41
  • Maybe there's some difference you can find with Feedback Assistant? e.g. When enrolling a macOS system in beta builds with the Beta Access Utility, the app is added to the Dock and aliased in /Utilities Commented Jul 8, 2020 at 17:21
  • It's good question which I have too. I can think of loads of janky ways to do it but none offline, sandboxed and without hardcoding anything. The best I can come up with is to encode a "tested with version" into each release of the app. Then compare the host OS version and if the version is higher (excluding the last digit), display an "untested OS" warning. But Apple changing the numbering scheme to 11.0 makes it hard to predict the meaning of the numbers now. Will the next one be 12.0? What will 11.1 mean? Could also test for if it's between June and October :) Commented Oct 24, 2020 at 8:17

2 Answers 2

3
+150

I believe you're out of luck. About This Mac uses PrivateFrameworks/Seeding.framework, here the important disassembly:

/* @class SDBuildInfo */
+(char)currentBuildIsSeed {
    return 0x0;
}

So it seems this is a build time compiler flag. The plists in the framework don't contain this flag unfortunately.

Sample private API usage: kaloprominat/currentBuildIsSeed.py

For the crazy ones: It would be possible to read the binary and compare the assembly for the function. I'd start with the class-dump code, which gets you different fat binaries and the function offset.

Sign up to request clarification or add additional context in comments.

2 Comments

That's good thinking, but that won't work for sandboxed apps, which I mentioned as a constraint.
@catlan, After further research on this method I've been able to access the bundle directly and retrieve this value.
0

This is far from perfect but macOS BigSur release notes mention:

Known Issues
In Swift, the authorizationStatus() property of CLLocationManager is incorrectly exposed as a method instead of a property. (62853845)

This^ is new API introduced in MacOS11 / iOS14

So one could detect this for this particular beta.

import CoreLocation
func isMacOS11Beta() -> Bool {
    var propertiesCount = UInt32()
    let classToInspect = CLLocationManager.self
    var isMacOS11OrHigher = false
    var isMacOS11Beta = false
    let propertiesInAClass = class_copyPropertyList(CLLocationManager.self, &propertiesCount)
    if classToInspect.responds(to: NSSelectorFromString("authorizationStatus")) {
        isMacOS11OrHigher = true
        isMacOS11Beta = true
        for i in 0 ..< Int(propertiesCount) {
            if let property = propertiesInAClass?[i], let propertyName = NSString(utf8String: property_getName(property)) as String? {
                if propertyName == "authorizationStatus" {
                    isMacOS11Beta = false
                }
            }
        }
        free(propertiesInAClass)
    }
    return isMacOS11OrHigher && isMacOS11Beta
}

1 Comment

That's clever, but it will most likely not work with future betas, so not very useful. I need something that works with all the betas, ideally with betas next year too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.