2

我希望能够以某种方式检测我的应用程序是否在 macOS 11 的 beta 版本上运行,因为我想告知用户一些已知的错误。我只想向 macOS 11 beta 用户显示这样的警报,这意味着既不是 macOS 10.15 用户也不是 macOS 11 最终版本的用户。我当然可以提交一个应用程序更新以在 macOS 11 接近完成时删除警报,但如果有一些可重复使用的东西我可以在多个应用程序和未来的 macOS beta 版本中使用,那就太好了。

约束:

  • 该应用程序是沙盒的。
  • 该应用程序位于 App Store 中,因此没有私有 API。
  • 该应用程序没有网络权限,因此检测需要离线。
  • 我不想捆绑已知 macOS 内部版本号的列表并进行比较。

我的想法是,也许可以使用某种嗅探。当 macOS 版本是 beta 版本时,可能有一些 API 会返回不同的结果。

4

2 回答 2

3

我相信你运气不好。About This Mac使用PrivateFrameworks/Seeding.framework,这里是重要的反汇编:

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

所以这似乎是一个构建时编译器标志。不幸的是,框架中的 plist 不包含此标志。

私有 API 使用示例:kaloprominat/currentBuildIsSeed.py

对于疯狂的人:可以读取二进制文件并比较函数的程序集。我将从类转储代码开始,它会为您提供不同的胖二进制文件和函数偏移量。

于 2020-07-07T20:28:53.413 回答
0

这远非完美,但 macOS BigSur发行说明提到:

已知问题
在 Swift 中,CLLocationManager 的 authorizationStatus() 属性被错误地公开为方法而不是属性。(62853845)

This^ 是MacOS11 / iOS14 中引入的新API

因此,人们可以针对这个特定的 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
}
于 2020-07-11T09:28:14.740 回答