Check OS version in Swift?
For iOS, try:
var systemVersion = UIDevice.current.systemVersion
For OS X, try:
var systemVersion = NSProcessInfo.processInfo().operatingSystemVersion
If you just want to check if the users is running at least a specific version, you can also use the following Swift 2 feature which works on iOS and OS X:
if #available(iOS 9.0, *) {
// use the feature only available in iOS 9
// for ex. UIStackView
} else {
// or use some work around
}
BUT it is not recommended to check the OS version. It is better to check if the feature you want to use is available on the device than comparing version numbers.
For iOS, as mentioned above, you should check if it responds to a selector;
eg.:
if (self.respondsToSelector(Selector("showViewController"))) {
self.showViewController(vc, sender: self)
} else {
// some work around
}
How do I determine the OS version at runtime in OS X or iOS (without using Gestalt)?
On OS X 10.10 (and iOS 8.0), you can use [[NSProcessInfo processInfo] operatingSystemVersion]
which returns a NSOperatingSystemVersion
struct, defined as
typedef struct {
NSInteger majorVersion;
NSInteger minorVersion;
NSInteger patchVersion;
} NSOperatingSystemVersion;
There is also a method in NSProcessInfo
that will do the comparison for you:
- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version
Beware, although documented to be available in OS X 10.10 and later, both operatingSystemVersion
and isOperatingSystemAtLeastVersion:
exist on OS X 10.9 (probably 10.9.2) and work as expected. It means that you must not test if NSProcessInfo
responds to these selectors to check if you are running on OS X 10.9 or 10.10.
On iOS, these methods are effectively only available since iOS 8.0.
Swift MacOS know the version of the OS and Xcode
For the macOS version, you can indeed get it from ProcessInfo.processInfo.operatingSystemVersion
.
For the Xcode version, you can first find where Xcode's bundle is from its bundle ID, find its bundle, and get the version from its bundle's Info.plist as a string.
guard let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.dt.Xcode"),
let bundle = Bundle(url: url) else {
print("Xcode is not installed")
exit(1)
}
guard let infoDict = bundle.infoDictionary,
let version = infoDict["CFBundleShortVersionString"] as? String else {
print("No version found in Info.plist")
exit(1)
}
print(version) // Example output: 13.1
You can replace the let url = ...
step with a NSOpenPanel
prompt to let the user choose where their Xcode is installed too.
How do I see which version of Swift I'm using?
Project build settings have a block 'Swift Compiler - Languages', which stores information about Swift Language Version in key-value format. It will show you all available (supported) Swift Language Version for your Xcode and active version also by a tick mark.
Project ► (Select Your Project Target) ► Build Settings ► (Type
'swift_version' in the Search bar) Swift Compiler Language ► Swift Language
Version ► Click on Language list to open it (and there will be a tick mark on any one of list-item, that will be current swift version).
Look at this snapshot, for easy understanding:
With help of following code, programmatically you can find Swift version supported by your project.
#if swift(>=5.7)
print("Hello, Swift 5.7")
#elseif swift(>=5.6)
print("Hello, Swift 5.6")
#elseif swift(>=5.5)
print("Hello, Swift 5.5")
#elseif swift(>=5.4)
print("Hello, Swift 5.4")
#elseif swift(>=5.3)
print("Hello, Swift 5.3")
#elseif swift(>=5.2)
print("Hello, Swift 5.2")
#elseif swift(>=5.1)
print("Hello, Swift 5.1")
#elseif swift(>=5.0)
print("Hello, Swift 5.0")
#elseif swift(>=4.2)
print("Hello, Swift 4.2")
#elseif swift(>=4.1)
print("Hello, Swift 4.1")
#elseif swift(>=4.0)
print("Hello, Swift 4.0")
#elseif swift(>=3.2)
print("Hello, Swift 3.2")
#elseif swift(>=3.0)
print("Hello, Swift 3.0")
#elseif swift(>=2.2)
print("Hello, Swift 2.2")
#elseif swift(>=2.1)
print("Hello, Swift 2.1")
#elseif swift(>=2.0)
print("Hello, Swift 2.0")
#elseif swift(>=1.2)
print("Hello, Swift 1.2")
#elseif swift(>=1.1)
print("Hello, Swift 1.1")
#elseif swift(>=1.0)
print("Hello, Swift 1.0")
#endif
Here is result using Playground (with Xcode 11.x)
How to determine device type from Swift? (OS X or iOS)
If you're building for both iOS and macOS (and maybe for watchOS and tvOS, too), you're compiling at least twice: once for each platform. If you want different code to execute on each platform, you want a build-time conditional, not a run-time check.
Swift has no preprocessor, but it does have conditional build directives — and for the most part, they look like the C equivalent.
#if os(iOS) || os(watchOS) || os(tvOS)
let color = UIColor.red
#elseif os(macOS)
let color = NSColor.red
#else
println("OMG, it's that mythical new Apple product!!!")
#endif
You can also use build configurations to test for architecture (x86_64
, arm
, arm64
, i386
), Target environment (iOS simulator or Mac Catalyst), or -D
compiler flags (including the DEBUG
flag defined by the standard Xcode templates). Don’t assume that these things go together — Apple has announced macOS on arm64 to ship in 2020, so arm64 doesn’t imply iOS, and iOS Simulator doesn’t imply x86, etc.
See Compiler Control statements in The Swift Programming Language.
(If you want to distinguish which kind of iOS device you're on at runtime, use the UIDevice
class just like you would from ObjC. It's typically more useful and safe to look at the device attributes that are important to you rather than a device name or idiom — e.g. use traits and size classes to lay out your UI, check Metal for the GPU capabilities you require, etc.)
How to check Mac OS X version at runtime
Update:
Use #define NSAppKitVersionNumber10_10_Max 1349
Old:
From 10.11 SDK
#define NSAppKitVersionNumber10_7_2 1138.23
#define NSAppKitVersionNumber10_7_3 1138.32
#define NSAppKitVersionNumber10_7_4 1138.47
#define NSAppKitVersionNumber10_8 1187
#define NSAppKitVersionNumber10_9 1265
#define NSAppKitVersionNumber10_10 1343
#define NSAppKitVersionNumber10_10_2 1344
#define NSAppKitVersionNumber10_10_3 1347
for 10.10.4 Its 1348.0
(From NSLog output)
They increase decimal part for 10.10.x constant.
The workaround is to use CFBundleVersion
value /System/Library/Frameworks/AppKit.framework/Resources/Info.plist
on 10.11.
if (NSAppKitVersionNumber < 1391.12)
{
/* On a 10.10.x or earlier system */
}
NOTE: My OS X 10.11 build version is 15A244a. If someone have first build , Please update the value in if condition.
How can I programmatically find Swift's version?
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)
}
How to get actual name of Mac Operating System instead of version?
There is no API that I know of that would produce the product name of the current OS version. Even grep
ping for the product name in system locations yields surprisingly few results, and most of those in private frameworks. The only promising non-private match I found is in the Setup Assistant.app
, and requires a horrible kludge to extract from a longer string:
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/Localizable.strings"];
NSString *productName = [dict objectForKey:@"INSTALLATION_COMPLETE"];
if (productName) {
NSRange r = [productName rangeOfString:@" has been"];
if (r.location != NSNotFound) {
productName = [productName substringToIndex:r.location];
} else {
productName = nil;
}
}
This happens to work for Yosemite and El Capitan, and produces "OS X Yosemite" and "OS X El Capitan". But even with these two versions the kludgey nature reveals itself; the El Capitan string contains non-breakable spaces…
Apart from this (or a similar kludge using other files not meant to be used this way), one can of course obtain the numeric version and match it against a list of known product names, which would be my recommended solution, perhaps with the above kludge as a fallback.
Related Topics
Programmatically Place Partial Image Over Another in UIview Using Swift 3
How to Get Wkwebview to Work in Swift and for an Macos App
Cannot Convert Value of Type 'X' to Expected Argument Type 'X'
Issue with Returning a Directory Enumerator from Nsfilemanager Using Enumeratoraturl in Swift
Reachability Change Notification Should Be Called Only Once
Dependency Injection in View Controller
Get Output Frames Failed, State 8196
Error: 'string' Is Not Convertible to 'string!'
Multiline Editable Text Field in Swiftui
How to Create a Smooth Colour Change Animation Using Swiftui? (Example in Question)
Custom Radix Columns (+Special Characters)
How to Use @Fetchrequest Outside a View
Nstoolbarflexiblespaceitem Is Constraint to Nssplitviewitem in Swift
Realm: Predicate Returning Lazyfiltercollection - How to Convert to Results<T>
How to Present a UIcollectionview in Swiftui with UIviewcontrollerrepresentable
How to Detect If The User Was Deleted from Firebase Auth