如何以编程方式找到 Swift 的版本?

Posted

技术标签:

【中文标题】如何以编程方式找到 Swift 的版本?【英文标题】:How can I programmatically find Swift's version? 【发布时间】: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 版本。 这就是我的意思:***.com/questions/27242690/…。也许不一样,但与您的问题有关。 @Martin:是的,它或多或少是一样的。我不关心获取 Swift 版本的机制,只要它有效 :-) 【参考方案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)

以上是关于如何以编程方式找到 Swift 的版本?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中以编程方式启用/禁用菜单对象

Swift - 以编程方式创建视图问题,无法找到存储的属性

iOS Swift - 如何以编程方式为所有按钮分配默认操作

以编程方式将标签添加到 Swift 中的消息应用程序?

如何使用 Swift 以编程方式让 Mac 进入睡眠状态

在 Swift 中以编程方式从 MainViewController 切换到 .xib 视图?