45

I know I can find the version of Swift I'm running right now reverting to a Terminal and typing:

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

Also, I've been reading about the Preprocessor Macros in Swift, but no luck finding a Swift version constant.

As Swift 1.2 approaches it will be nice to flag old code that only runs on Swift 1.1 (Xcode up to 6.2) or new code that needs Xcode 6.3 (Swift 1.2)

Note: I can also use system() to do something like:

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

Then open somefile.txt, but rather prefer some simpler solution

Diego Freniche
  • 5,225
  • 3
  • 32
  • 45
  • I am pretty sure that this has been asked before (without a satisfying solution at that time) but I cannot find it ... – Martin R Mar 19 '15 at 09:25
  • I've found discussions about finding out Frameworks versions, but not about the language itself. Any information will be appreciated – Diego Freniche Mar 19 '15 at 09:28
  • Just a warning about the call out to xcrun. If there are multiple Xcode versions installed I'm not sure that the response you get will necessarily be for the Swift version that your app is running in. – Joseph Lord Mar 19 '15 at 09:49
  • 1
    This is what I meant: http://stackoverflow.com/questions/27242690/gcc-version-equivalent-for-swift-code. Perhaps not the same, but related to your question. – Martin R Mar 19 '15 at 13:37
  • @Martin: yes it's more or less the same. I don't care about the mechanism for getting Swift's version as long as it works :-) – Diego Freniche Mar 19 '15 at 16:21
  • Why do you want to know is it just to keep your code up to date? AFAIK, Apple don't make this available but there may be other ways to achieve what you want. – Rog Apr 09 '15 at 12:15
  • I want to check because different versions of Swift have different features even different semantics for same constructs (inmutable arrays at the beginning, for example). So it will be a needed feature for library versioning / testing – Diego Freniche Apr 09 '15 at 14:21

6 Answers6

36

You can use conditional compilation directives to test for the specific Swift version used to build your project:

#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
Adam
  • 26,549
  • 8
  • 62
  • 79
crishoj
  • 5,660
  • 4
  • 32
  • 31
15

Finally got a workaround to do this. I'm using the constants prefixed with __ you can observe in your Playground. This would have been easier with some level of reflection, but...

__IPHONE_OS_VERSION_MAX_ALLOWED is 80200, meaning __IPHONE_8_2 for Xcode 6.2 (Swift 1.1) but its value is 80300 (__IPHONE_8_3) in Xcode 6.3 (Swift 1.2)

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

isSwift12()

So now in your library you can fail fast and tell your user Swift's version is not correct using this:

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

Swift will give you a nice:

assertion failed: Need Swift 12: file , line 20

UPDATE WWDC 2015 - Swift 2.0

As stated in Apple's Swift blog, in Swift 2.0 we have #available blocks to check for certain OS versions in our code. An example should be:

if #available(OSX 10.11, *) {
    monochromeFilter!.setValue(CIColor(red: 0.5, green: 0.5, blue: 0.5), forKey:kCIInputColorKey)
} else {
    // Fallback on earlier versions
}
Community
  • 1
  • 1
Diego Freniche
  • 5,225
  • 3
  • 32
  • 45
  • Good answer. Might be worth adding that this that the max allowed is normally (always?) set to the current release for the Xcode. Also as this is presumably for libraries it might be worth adding tests to the example that cover OS X. Finally you have Xcode 6.2 implying Swift 1.2 but that is still Swift 1.1. Swift 1.2 came in Xcode 6.3 didn't it? – Joseph Lord Apr 17 '15 at 09:02
  • Fixed! Thanks for the heads up! Yes, Xcode 6.2 == Swift 1.1 / Xcode 6.3 == Swift 1.2. I __hope__ that constant will keep updated in the future. I'm just running out of ideas :-D – Diego Freniche Apr 17 '15 at 09:05
7

Swift 3.1 extends the @available attribute to support specifying Swift version numbers in addition to its existing platform versions.

// 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)
}
byJeevan
  • 3,728
  • 3
  • 37
  • 60
  • [Reference](https://github.com/apple/swift-evolution/blob/master/proposals/0141-available-by-swift-version.md) for my answer. – byJeevan Mar 31 '17 at 16:15
  • Much better solution instead of comparing a version with if-else condition loops!! – byJeevan Oct 29 '18 at 07:15
-1

From your comment:

I want to check because different versions of Swift have different features

You should not check the version of your programming language in order to use some features or not. This approach is much better:

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

Just check whether a method is available or not.

dehlen
  • 7,325
  • 4
  • 43
  • 71
  • Well, when you have a language changing that fast, it's useful to check language's version to put a nice warning beforehand so the user knows the library is trying to use doesn't compile because of Swift's version changes. Also: this only works with NSObject descendant classes, or Swift classes with @objc, with pure Swift classes always return `nil`. Finally: you're stating your opinion, not answering the question. – Diego Freniche Apr 17 '15 at 07:54
  • That doesn't help when the problem is a compiler (ie syntactical) error between Swift versions. – CodeSmile Aug 06 '15 at 18:39
-1

Open up a command line on your Mac computer

type swift -version, without the double dashes, which doesn't work any more for Xcode 11/Swift 5.2.2

Of course, you'll have to update to latest IDE, which always downloads the latest version of both Xcode, languages, compilers and tools... EVERYTHING is updated. If you do that, that solution works for sure.

bodycode
  • 1
  • 1
  • Your answer is off-topic. OP knows they can get the version from the command line, they mention it in their question. What OP wants is to get the version **programmatically**, using Swift. – Eric Aya Aug 09 '20 at 12:35
-6

For iOS :

var systemVersion = UIDevice.currentDevice().systemVersion;

For OSX :

var systemVersion = NSProcessInfo.processInfo().operatingSystemVersion;

K.

  • 7
    Unfortunately, this is not a solution to this question. From the docs: "systemVersionProperty: The current version of the operating system.". This gives you the version of the OS you're running in your device, not the version of Swift your program is running on. For example, in OS X 10.10 you can run both Xcode 6.3 (Swift 1.2) & Xcode 6.2 (Swift 1.1) – Diego Freniche Apr 16 '15 at 14:48