How to determine device type from Swift? (OS X or iOS)
This should provide you with every use case:
#if os(OSX)
print("macOS")
#elseif os(watchOS)
print("watchOS")
#elseif os(tvOS)
print("tvOS")
#elseif os(iOS)
#if targetEnvironment(macCatalyst)
print("macOS - Catalyst")
#else
print("iOS")
#endif
#endif
Updating for Mac Catalyst. You may also now use the following to determine if iOS or Mac Catalyst:
let color: UIColor
#if targetEnvironment(macCatalyst)
color = .systemRed
#else
color = .systemBlue
#endif
For example.
Since Swift 4.2 you can replace
#if os(iOS) || os(watchOS) || os(tvOS)
let color = UIColor.redColor()
#elseif os(OSX)
let color = NSColor.redColor()
#else
println("OMG, it's that mythical new Apple product!!!")
#endif
By
#if canImport(UIKit)
let color = UIColor.redColor()
#elseif os(OSX)
let color = NSColor.redColor()
#else
#error("OMG, it's that mythical new Apple product!!!")
#endif
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.)