【问题标题】:How can I programmatically find Swift's version?如何以编程方式找到 Swift 的版本?
【发布时间】:2015-05-22 07:47:15
【问题描述】:

我知道我现在可以找到我正在运行的 Swift 版本,然后恢复到终端并输入:

xcrun swift --version
Swift version 1.1 (swift-600.0.57.4)
Target: x86_64-apple-darwin13.4.0

另外,我一直在阅读 Swift 中的 Preprocessor Macros,但没有找到 Swift 版本常量。

随着 Swift 1.2 的临近,标记仅在 Swift 1.1(Xcode 最高 6.2)上运行的旧代码或需要 Xcode 6.3(Swift 1.2)的新代码会很好

注意:我也可以使用 system() 来执行以下操作:

system("xcrun swift --version | grep version > somefile.txt")

然后打开 somefile.txt,但更喜欢一些更简单的解决方案

【问题讨论】:

  • 我很确定以前有人问过这个问题(当时没有令人满意的解决方案)但我找不到它......
  • 我发现了关于查找框架版本的讨论,但不是关于语言本身的讨论。任何信息将不胜感激
  • 只是关于调用 xcrun 的警告。如果安装了多个 Xcode 版本,我不确定您得到的响应是否一定是您的应用程序正在运行的 Swift 版本。
  • 这就是我的意思:stackoverflow.com/questions/27242690/…。也许不一样,但与您的问题有关。
  • @Martin:是的,它或多或少是一样的。我不关心获取 Swift 版本的机制,只要它有效 :-)

标签: ios macos swift xcode6


【解决方案1】:

您可以使用条件编译指令来测试用于构建项目的特定 Swift 版本:

#if swift(>=5.0)
print("Hello, Swift 5!")
#elseif swift(>=4.0)
print("Hello, Swift 4!")
#elseif swift(>=3.0)
print("Hello, Swift 3!")
#elseif swift(>=2.2)
print("Hello, Swift 2.2!")
#elseif swift(>=2.1)
print("Hello, Swift 2.1!")
#endif

【讨论】:

    【解决方案2】:

    终于找到了解决方法。我正在使用前缀为 __ 的常量,您可以在 Playground 中观察到。使用某种级别的reflection 会更容易,但是...

    __IPHONE_OS_VERSION_MAX_ALLOWED 是 80200,对于 Xcode 6.2 (Swift 1.1) 意味着 __IPHONE_8_2,但在 Xcode 6.3 (Swift 1.2) 中它的值是 80300 (__IPHONE_8_3)

    func isSwift12() -> Bool {
      return __IPHONE_OS_VERSION_MAX_ALLOWED == 80300
    }
    
    isSwift12()
    

    所以现在在你的库中你可以快速失败并告诉你的用户 Swift 的版本是不正确的:

    assert(isSwift12(), "Need Swift 12")
    

    Swift 会给你一个很好的:

    断言失败:需要 Swift 12:文件,第 20 行

    更新 WWDC 2015 - Swift 2.0

    正如 Apple 的 Swift blog 中所述,在 Swift 2.0 中,我们有 #available 块来检查我们代码中的某些操作系统版本。一个例子应该是:

    if #available(OSX 10.11, *) {
        monochromeFilter!.setValue(CIColor(red: 0.5, green: 0.5, blue: 0.5), forKey:kCIInputColorKey)
    } else {
        // Fallback on earlier versions
    }
    

    【讨论】:

    • 好答案。可能值得补充的是,允许的最大值通常(总是?)设置为 Xcode 的当前版本。此外,由于这可能适用于库,因此可能值得在涵盖 OS X 的示例中添加测试。最后,您有 Xcode 6.2 暗示 Swift 1.2,但这仍然是 Swift 1.1。 Swift 1.2 出现在 Xcode 6.3 中不是吗?
    • 已修复!感谢您的提醒!是的,Xcode 6.2 == Swift 1.1 / Xcode 6.3 == Swift 1.2。我希望该常量将来会不断更新。我只是没有想法了:-D
    【解决方案3】:

    Swift 3.1 扩展了 @available 属性,以支持在现有平台版本之外指定 Swift 版本号。

    // Swift 3.1
    
    @available(swift 3.1)
    func intVersion(number: Double) -> Int? {
      return Int(exactly: number)
    }
    
    @available(swift, introduced: 3.0, obsoleted: 3.1)
    func intVersion(number: Double) -> Int {
      return Int(number)
    }
    

    【讨论】:

    • Reference 我的回答。
    • 更好的解决方案,而不是将版本与 if-else 条件循环进行比较!
    【解决方案4】:

    来自您的评论:

    我想检查一下,因为不同版本的 Swift 有不同的功能

    您不应为了使用某些功能而检查您的编程语言的版本。这种方法要好得多:

    if (self.respondsToSelector(Selector("yourMethodSelector"))) {
        self.yourMethodSelector(test, sender: self)
    } else {
        //error handling
    }
    

    只检查一个方法是否可用。

    【讨论】:

    • 好吧,当你的语言变化如此之快时,检查语言的版本以提前发出警告是很有用的,这样用户就知道由于 Swift 的版本变化,试图使用的库无法编译.另外:这仅适用于 NSObject 后代类,或带有 @objc 的 Swift 类,纯 Swift 类总是返回 nil。最后:你是在陈述你的观点,而不是在回答问题。
    • 当问题是 Swift 版本之间的编译器(即语法)错误时,这无济于事。
    【解决方案5】:

    在你的 Mac 电脑上打开命令行

    键入 swift -version,不带双破折号,这对于 Xcode 11/Swift 5.2.2 不再有效

    当然,您必须更新到最新的 IDE,它总是会下载最新版本的 Xcode、语言、编译器和工具……一切都已更新。如果您这样做,那么该解决方案肯定有效。

    【讨论】:

    • 你的回答离题了。 OP 知道他们可以从命令行获取版本,他们在问题中提到了它。 OP 想要的是使用 Swift以编程方式获取版本。
    【解决方案6】:

    对于 iOS

    var systemVersion = UIDevice.currentDevice().systemVersion;

    对于 OSX

    var systemVersion = NSProcessInfo.processInfo().operatingSystemVersion;

    K.

    【讨论】:

    • 不幸的是,这不是这个问题的解决方案。来自文档:“systemVersionProperty:操作系统的当前版本。”。这为您提供了您在设备中运行的操作系统版本,而不是您的程序运行的 Swift 版本。例如,在 OS X 10.10 中,您可以同时运行 Xcode 6.3 (Swift 1.2) 和 Xcode 6.2 (Swift 1.1)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多