How to determine device type from Swift? (OS X or iOS)

IosMacosSwift

Ios Problem Overview


I know Swift is relatively new, but I was wondering if there was a way to determine the device type?

(Like you used to be able to do with a #define)?

Mainly I would like to know how to differentiate OS X or iOS. I have found nothing on the subject.

Ios Solutions


Solution 1 - 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.)

Solution 2 - 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

Solution 3 - Ios

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

Solution 4 - Ios

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.

Solution 5 - Ios

Swift 4 (updated Jul 21, 2020)

enum TargetDevice {
    case nativeMac
    case iPad
    case iPhone
    case iWatch
    
    public static var currentDevice: Self {
        var currentDeviceModel = UIDevice.current.model
        #if targetEnvironment(macCatalyst)
        currentDeviceModel = "nativeMac"
        #elseif os(watchOS)
        currentDeviceModel = "watchOS"
        #endif
        
        if currentDeviceModel.starts(with: "iPhone") {
            return .iPhone
        }
        if currentDeviceModel.starts(with: "iPad") {
            return .iPad
        }
        if currentDeviceModel.starts(with: "watchOS") {
            return .iWatch
        }
        return .nativeMac
    }
}

Usage:

print(TargetDevice.currentDevice)

Solution 6 - Ios

Swift 5 and Xcode 13

I you are using "Scale interface to Match iPad, you cannot use UIDevice.current.userInterfaceIdiom , because it will return an .iPad value. However it is recommended to use targetEnvironment instead. Here is example code:

    #if targetEnvironment(macCatalyst)
            //execute your code for mac device
    #endif

If you are NOT using scale interface to Match iPad,but rather using "Optimize interface for mac" you can use this code for determning device:

UIDevice.current.userInterfaceIdiom == .mac

Here is apple documantation providing more info.

mac project setup

Solution 7 - Ios

var device = UIDevice.currentDevice().model 

This code worked for me. I have implemented that on textfield and keyboard dismissing part. See below.

func textFieldShouldBeginEditing(textField: UITextField) -> Bool
{
    
    print(device)
    
    if (textField.tag  == 1 && (device == "iPhone" || device == "iPhone Simulator" ))
    {
        var scrollPoint:CGPoint = CGPointMake(0,passwordTF.frame.origin.y/2);
        LoginScroll!.setContentOffset(scrollPoint, animated: true);
    }
    else if (textField.tag  == 2 && (device == "iPhone" || device == "iPhone Simulator"))
    {
        var scrollPoint:CGPoint = CGPointMake(0,passwordTF.frame.origin.y/1.3);
        LoginScroll!.setContentOffset(scrollPoint, animated: true);
    }
    
    return true
    
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1947561View Question on Stackoverflow
Solution 1 - IosricksterView Answer on Stackoverflow
Solution 2 - IosadamfootdevView Answer on Stackoverflow
Solution 3 - IosraedView Answer on Stackoverflow
Solution 4 - Iosuser12465607View Answer on Stackoverflow
Solution 5 - IosdphansView Answer on Stackoverflow
Solution 6 - IosMr.SwiftOakView Answer on Stackoverflow
Solution 7 - IosAlvin GeorgeView Answer on Stackoverflow