ChatGPT解决这个技术问题 Extra ChatGPT

Detect current device with UI_USER_INTERFACE_IDIOM() in Swift

What is the equivalent of UI_USER_INTERFACE_IDIOM() in Swift to detect between iPhone and iPad?

I get an Use of unresolved identifier error when compiling in Swift.


E
EJZ

When working with Swift, you can use the enum UIUserInterfaceIdiom, defined as:

enum UIUserInterfaceIdiom : Int {
    case unspecified
    
    case phone // iPhone and iPod touch style UI
    case pad   // iPad style UI (also includes macOS Catalyst)
}

So you can use it as:

UIDevice.current.userInterfaceIdiom == .pad
UIDevice.current.userInterfaceIdiom == .phone
UIDevice.current.userInterfaceIdiom == .unspecified

Or with a Switch statement:

    switch UIDevice.current.userInterfaceIdiom {
    case .phone:
        // It's an iPhone
    case .pad:
        // It's an iPad (or macOS Catalyst)

     @unknown default:
        // Uh, oh! What could it be?
    }

UI_USER_INTERFACE_IDIOM() is an Objective-C macro, which is defined as:

#define UI_USER_INTERFACE_IDIOM() \ ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? \ [[UIDevice currentDevice] userInterfaceIdiom] : \ UIUserInterfaceIdiomPhone)

Also, note that even when working with Objective-C, the UI_USER_INTERFACE_IDIOM() macro is only required when targeting iOS 3.2 and below. When deploying to iOS 3.2 and up, you can use [UIDevice userInterfaceIdiom] directly.


Never mind. I got it working with if UIDevice.currentDevice().userInterfaceIdiom == .Pad
As Tony mentioned in one of the answers below, UI_USER_INTERFACE_IDIOM in Swift apps crashes when the app is deployed via TestFlight. Strangely, it works when the app is uploaded directly to device from X-Code. I've also hit this bug.
@Zmey Yes, my app has also got rejected because UI_USER_INTERFACE_IDIOM crashes in review, very strange
In Swift 3 UIDevice.currentDevice().userInterfaceIdiom becomes UIDevice.current.userInterfaceIdiom
If your app is iPhone only, this method will not work correctly, you will always get .phone, check Ricardo's answer.
C
Cœur

You should use this GBDeviceInfo framework or ...

Apple defines this:

public enum UIUserInterfaceIdiom : Int {

    case unspecified

    case phone // iPhone and iPod touch style UI

    case pad // iPad style UI

    @available(iOS 9.0, *)
    case tv // Apple TV style UI

    @available(iOS 9.0, *)
    case carPlay // CarPlay style UI
}

so for the strict definition of the device can be used this code

struct ScreenSize
{
    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}

struct DeviceType
{
    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_5          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_6_7          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_6P_7P         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0
    static let IS_IPAD_PRO          = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0
}

how to use

if DeviceType.IS_IPHONE_6P_7P {
    print("IS_IPHONE_6P_7P")
}

to detect iOS version

struct Version{
    static let SYS_VERSION_FLOAT = (UIDevice.current.systemVersion as NSString).floatValue
    static let iOS7 = (Version.SYS_VERSION_FLOAT < 8.0 && Version.SYS_VERSION_FLOAT >= 7.0)
    static let iOS8 = (Version.SYS_VERSION_FLOAT >= 8.0 && Version.SYS_VERSION_FLOAT < 9.0)
    static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0)
}

how to use

if Version.iOS8 {
    print("iOS8")
}

I like struct ScreenSize/DeviceType approach since it works in Simulator
approved answer should go to this neat answer
Huge love from INDIA, appreciate you efforts, Thanks you so much for sharing and making better Stackoverflow ;)
What's the updated code? In context to DEVICE_TYPE for iPhone 7 and 7P
N
Nikolay Suvandzhiev

if/else case:

 if UIDevice.current.userInterfaceIdiom == .pad {
     // iPad
 } else {
     // not iPad (iPhone, mac, tv, carPlay, unspecified)
 }

public enum UIUserInterfaceIdiom : Int { case Unspecified @available(iOS 3.2, *) case Phone // iPhone and iPod touch style UI @available(iOS 3.2, *) case Pad // iPad style UI @available(iOS 9.0, *) case TV // Apple TV style UI } Check out the definition of UIUserInterfaceIdiom.If it's not Pad, it could be Phone, TV, Unspecified.
J
Jonas Deichelmann

Swift 2.0 & iOS 9 & Xcode 7.1

// 1. request an UITraitCollection instance
let deviceIdiom = UIScreen.mainScreen().traitCollection.userInterfaceIdiom

// 2. check the idiom
switch (deviceIdiom) {

case .Pad:
    print("iPad style UI")
case .Phone:
    print("iPhone and iPod touch style UI")
case .TV: 
    print("tvOS style UI")
default:
    print("Unspecified UI idiom")

}

Swift 3.0 and Swift 4.0

// 1. request an UITraitCollection instance
let deviceIdiom = UIScreen.main.traitCollection.userInterfaceIdiom

// 2. check the idiom
switch (deviceIdiom) {

case .pad:
    print("iPad style UI")
case .phone:
    print("iPhone and iPod touch style UI")
case .tv: 
    print("tvOS style UI")
default:
    print("Unspecified UI idiom")
}

Use UITraitCollection. The iOS trait environment is exposed though the traitCollection property of the UITraitEnvironment protocol. This protocol is adopted by the following classes:

UIScreen

UIWindow

UIViewController

UIPresentationController

UIView


r
ricardo

I do in that way:

UIDevice.current.model

It shows the name of the device.

To check if is iPad or iPhone:

if ( UIDevice.current.model.range(of: "iPad") != nil){
    print("I AM IPAD")
} else {
    print("I AM IPHONE")
}

definitely best solution, for me at least. Check for userInterfaceIdiom has a problem: if your app is for iPhone only but you launch app on iPad, userInterfaceIdiom is == .Phone
Definitely the best solution. Good one.
B
Brody Robertson

Swift 4.2 - 5.1 Extension

 public extension UIDevice {

    class var isPhone: Bool {
        return UIDevice.current.userInterfaceIdiom == .phone
    }

    class var isPad: Bool {
        return UIDevice.current.userInterfaceIdiom == .pad
    }

    class var isTV: Bool {
        return UIDevice.current.userInterfaceIdiom == .tv
    }

    class var isCarPlay: Bool {
        return UIDevice.current.userInterfaceIdiom == .carPlay
    }
}

Usage

if UIDevice.isPad {
   // Do something
}

C
Community

Try adding an extension like this:

    public extension UIDevice {

    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8 where value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }

        switch identifier {
        case "iPod5,1":                                 return "iPod Touch 5"
        case "iPod7,1":                                 return "iPod Touch 6"
        case "iPhone3,1", "iPhone3,2", "iPhone3,3":     return "iPhone 4"
        case "iPhone4,1":                               return "iPhone 4s"
        case "iPhone5,1", "iPhone5,2":                  return "iPhone 5"
        case "iPhone5,3", "iPhone5,4":                  return "iPhone 5c"
        case "iPhone6,1", "iPhone6,2":                  return "iPhone 5s"
        case "iPhone7,2":                               return "iPhone 6"
        case "iPhone7,1":                               return "iPhone 6 Plus"
        case "iPhone8,1":                               return "iPhone 6s"
        case "iPhone8,2":                               return "iPhone 6s Plus"
        case "iPhone9,1", "iPhone9,3":                  return "iPhone 7"
        case "iPhone9,2", "iPhone9,4":                  return "iPhone 7 Plus"
        case "iPhone8,4":                               return "iPhone SE"
        case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2"
        case "iPad3,1", "iPad3,2", "iPad3,3":           return "iPad 3"
        case "iPad3,4", "iPad3,5", "iPad3,6":           return "iPad 4"
        case "iPad4,1", "iPad4,2", "iPad4,3":           return "iPad Air"
        case "iPad5,3", "iPad5,4":                      return "iPad Air 2"
        case "iPad2,5", "iPad2,6", "iPad2,7":           return "iPad Mini"
        case "iPad4,4", "iPad4,5", "iPad4,6":           return "iPad Mini 2"
        case "iPad4,7", "iPad4,8", "iPad4,9":           return "iPad Mini 3"
        case "iPad5,1", "iPad5,2":                      return "iPad Mini 4"
        case "iPad6,3", "iPad6,4", "iPad6,7", "iPad6,8":return "iPad Pro"
        case "AppleTV5,3":                              return "Apple TV"
        case "i386", "x86_64":                          return "Simulator"
        default:                                        return identifier
        }
    }

}

This is how you will use it:

let modelName = UIDevice.currentDevice().modelName

EDIT For simulator, you can try a solution here


nice, though testing with simulator just returns simulator. is there a way around this?
C
Community

Swift 2.x:

Adding to Beslav Turalov answer's the new entry iPad Pro can easily be find with this line

to detect iPad Pro

struct DeviceType
{
    ...
    static let IS_IPAD_PRO = UIDevice.currentDevice().userInterfaceIdiom == .Pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0
}

Swift 3 (TV and car added):

struct ScreenSize
{
    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}

struct DeviceType
{
    static let IS_IPHONE            = UIDevice.current.userInterfaceIdiom == .phone
    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_5          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_6          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_6P         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPHONE_7          = IS_IPHONE_6
    static let IS_IPHONE_7P         = IS_IPHONE_6P
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0
    static let IS_IPAD_PRO_9_7      = IS_IPAD
    static let IS_IPAD_PRO_12_9     = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0
    static let IS_TV                = UIDevice.current.userInterfaceIdiom == .tv
    static let IS_CAR_PLAY          = UIDevice.current.userInterfaceIdiom == .carPlay
}

struct Version{
    static let SYS_VERSION_FLOAT = (UIDevice.current.systemVersion as NSString).floatValue
    static let iOS7 = (Version.SYS_VERSION_FLOAT < 8.0 && Version.SYS_VERSION_FLOAT >= 7.0)
    static let iOS8 = (Version.SYS_VERSION_FLOAT >= 8.0 && Version.SYS_VERSION_FLOAT < 9.0)
    static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0)
    static let iOS10 = (Version.SYS_VERSION_FLOAT >= 10.0 && Version.SYS_VERSION_FLOAT < 11.0)
}

USAGE:

if DeviceType.IS_IPHONE_7P { print("iPhone 7 plus") }
if DeviceType.IS_IPAD_PRO_9_7 && Version.iOS10 { print("iPad pro 9.7 with iOS 10 version") }

r
raaz

In swift 4 & Xcode 9.2 , you can detect if a device is iPhone/iPad by below ways.

if (UIDevice.current.userInterfaceIdiom == .pad){
   print("iPad")
}
else{
   print("iPhone")
}

Another Way

    let deviceName = UIDevice.current.model
    print(deviceName);
    if deviceName == "iPhone"{
        print("iPhone")
    }
    else{
        print("iPad")
    }

d
drewster

Try this for check current device is iPhone or iPad:

Swift 5

struct Device {
    static let IS_IPAD = UIDevice.current.userInterfaceIdiom == .pad
    static let IS_IPHONE = UIDevice.current.userInterfaceIdiom == .phone
}

Use:

if(Device.IS_IPHONE){
    // device is iPhone
}if(Device.IS_IPAD){
    // device is iPad (or a Mac running under macOS Catalyst)
}else{
    // other
}

A
Abdullah Umer

Since iOS 13, UI_USER_INTERFACE_IDIOM has been deprecated. If your code is still in Obj-C, you can use the following:

if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
    // device is iPad
}

Where:

typedef NS_ENUM(NSInteger, UIUserInterfaceIdiom) {
    UIUserInterfaceIdiomUnspecified = -1,
    UIUserInterfaceIdiomPhone API_AVAILABLE(ios(3.2)), // iPhone and iPod touch style UI
    UIUserInterfaceIdiomPad API_AVAILABLE(ios(3.2)), // iPad style UI
    UIUserInterfaceIdiomTV API_AVAILABLE(ios(9.0)), // Apple TV style UI
    UIUserInterfaceIdiomCarPlay API_AVAILABLE(ios(9.0)), // CarPlay style UI
};

Thank you for the Obj-C answer.
More Obj-C aligned writing - [[UIDevice currentDevice] userInterfaceIdiom]
G
Giang

Thank you everybody support :))

UIDevice+Extensions.swift

import Foundation
import UIKit

extension UIDevice {
    static let modelName: String = {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }

         func mapToDevice(identifier: String) -> String { // swiftlint:disable:this cyclomatic_complexity
            #if os(iOS)
            switch identifier {
            case "iPod5,1":                                 return "iPod Touch 5"
            case "iPod7,1":                                 return "iPod Touch 6"
            case "iPhone3,1", "iPhone3,2", "iPhone3,3":     return "iPhone 4"
            case "iPhone4,1":                               return "iPhone 4s"
            case "iPhone5,1", "iPhone5,2":                  return "iPhone 5"
            case "iPhone5,3", "iPhone5,4":                  return "iPhone 5c"
            case "iPhone6,1", "iPhone6,2":                  return "iPhone 5s"
            case "iPhone7,2":                               return "iPhone 6"
            case "iPhone7,1":                               return "iPhone 6 Plus"
            case "iPhone8,1":                               return "iPhone 6s"
            case "iPhone8,2":                               return "iPhone 6s Plus"
            case "iPhone9,1", "iPhone9,3":                  return "iPhone 7"
            case "iPhone9,2", "iPhone9,4":                  return "iPhone 7 Plus"
            case "iPhone8,4":                               return "iPhone SE"
            case "iPhone10,1", "iPhone10,4":                return "iPhone 8"
            case "iPhone10,2", "iPhone10,5":                return "iPhone 8 Plus"
            case "iPhone10,3", "iPhone10,6":                return "iPhone X"
            case "iPhone11,2":                              return "iPhone XS"
            case "iPhone11,4", "iPhone11,6":                return "iPhone XS Max"
            case "iPhone11,8":                              return "iPhone XR"
            case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2"
            case "iPad3,1", "iPad3,2", "iPad3,3":           return "iPad 3"
            case "iPad3,4", "iPad3,5", "iPad3,6":           return "iPad 4"
            case "iPad4,1", "iPad4,2", "iPad4,3":           return "iPad Air"
            case "iPad5,3", "iPad5,4":                      return "iPad Air 2"
            case "iPad6,11", "iPad6,12":                    return "iPad 5"
            case "iPad7,5", "iPad7,6":                      return "iPad 6"
            case "iPad2,5", "iPad2,6", "iPad2,7":           return "iPad Mini"
            case "iPad4,4", "iPad4,5", "iPad4,6":           return "iPad Mini 2"
            case "iPad4,7", "iPad4,8", "iPad4,9":           return "iPad Mini 3"
            case "iPad5,1", "iPad5,2":                      return "iPad Mini 4"
            case "iPad6,3", "iPad6,4":                      return "iPad Pro 9.7 Inch"
            case "iPad6,7", "iPad6,8":                      return "iPad Pro 12.9 Inch"
            case "iPad7,1", "iPad7,2":                      return "iPad Pro 12.9 Inch 2. Generation"
            case "iPad7,3", "iPad7,4":                      return "iPad Pro 10.5 Inch"
            case "AppleTV5,3":                              return "Apple TV"
            case "AppleTV6,2":                              return "Apple TV 4K"
            case "AudioAccessory1,1":                       return "HomePod"
            case "i386", "x86_64":                          return "Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS"))"
            default:                                        return identifier
            }
            #elseif os(tvOS)
            switch identifier {
            case "AppleTV5,3": return "Apple TV 4"
            case "AppleTV6,2": return "Apple TV 4K"
            case "i386", "x86_64": return "Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "tvOS"))"
            default: return identifier
            }
            #endif
        }
        return mapToDevice(identifier: identifier)
    }()
}

enum DeviceName: String {
    case iPod_Touch_5 = "iPod Touch 5"
    case pod_Touch_6 = "Pod Touch 6"
    case iPhone_4 = "iPhone 4"
    case iPhone_4s = "iPhone 4s"
    case iPhone_5 = "iPhone 5"
    case iPhone_5c = "iPhone 5c"
    case iPhone_5s = "iPhone 5s"
    case iPhone_6 = "iPhone 6"
    case iPhone_6_Plus = "iPhone 6 Plus"
    case iPhone_6s = "iPhone 6s"
    case iPhone_6s_Plus = "iPhone 6s Plus"
    case iPhone_7 = "iPhone 7"
    case iPhone_7_Plus = "iPhone 7 Plus"
    case iPhone_SE = "iPhone SE"
    case iPhone_8 = "iPhone 8"
    case iPhone_8_Plus = "iPhone 8 Plus"
    case iPhone_X = "iPhone X"
    case iPhone_XS = "iPhone XS"
    case iPhone_XS_Max = "iPhone XS Max"
    case iPhone_XR = "iPhone XR"
    case iPad_2 = "iPad 2"
    case iPad_3 = "iPad 3"
    case iPad_4 = "iPad 4"
    case iPad_Air = "iPad Air"
    case iPad_Air_2 = "iPad Air 2"
    case iPad_5 = "iPad 5"
    case iPad_6 = "iPad 6"
    case iPad_Mini = "iPad Mini"
    case iPad_Mini_2 = "iPad Mini 2"
    case iPad_Mini_3 = "iPad Mini 3"
    case iPad_Mini_4 = "iPad Mini 4"
    case iPad_Pro_9_7_Inch = "iPad Pro 9.7 Inch"
    case iPad_Pro_12_9_Inch = "iPad Pro 12.9 Inch"
    case iPad_Pro_12_9_Inch_2_Generation = "iPad Pro 12.9 Inch 2. Generation"
    case iPad_Pro_10_5_Inch = "iPad Pro 10.5 Inch"
    case apple_TV = "Apple TV"
    case apple_TV_4K = "Apple TV 4K"
    case homePod = "HomePod"
}

SharedFunctions.swift

import Foundation
import UIKit
func isDevice(_ name: DeviceName) -> Bool {
    let modelName = UIDevice.modelName.replacingOccurrences(of: "Simulator", with: "").trimmed()
    if name.rawValue == modelName {
        return true
    }

    return false
}

String+Whitespace.swift

import Foundation

extension String {
   public func trimmed() -> String {
    return self.trimmingCharacters(in: .whitespacesAndNewlines)
  }
}

Y
YannSteph

Swift 2.0 & iOS 7+ / iOS 8+ / iOS 9+

public class Helper {
    public class var isIpad:Bool {
        if #available(iOS 8.0, *) {
            return UIScreen.mainScreen().traitCollection.userInterfaceIdiom == .Pad
        } else {
            return UIDevice.currentDevice().userInterfaceIdiom == .Pad
        }
    }
    public class var isIphone:Bool {
        if #available(iOS 8.0, *) {
            return UIScreen.mainScreen().traitCollection.userInterfaceIdiom == .Phone
        } else {
            return UIDevice.currentDevice().userInterfaceIdiom == .Phone
        }
    }
}

Use :

if Helper.isIpad {

}

OR

guard Helper.isIpad else {
    return
} 

Thanks @user3378170


Thanks @user3378170 for iOS 9
K
Kevin

FYI, I have used UI_USER_INTERFACE_IDIOM() for my app written in Swift. The app can be compiled well with XCode 6.3.1 without any warning on that command, runs well on Simulator (with any selected devices) and on all my real devices (iPhone, iPad) with iOS versions from 7.1 to 8.3.

However, the app crashed on Apple reviewers' devices (and was refused). That took me few days to detect the problem with few more re-uploads to iTunes Connect.

Now I use UIDevice.currentDevice().userInterfaceIdiom instead and my app can survive from such crashes.


Exactly correct. It does crash and caused me a lot of headache trying to figure out the issue.
The Swift compiler kept crashing whenever I used UI_USER_INTERFACE_IDIOM() in my code, without any error message. Very strange.
fwiw, Apple's doc now states "If your app runs in iOS 3.2 and later, use userInterfaceIdiom instead."
s
selva

If you want to check the current device whether its iPad or iPhone then you can use these line of code :

 if(UIDevice.currentDevice().userInterfaceIdiom == .Pad){

  }else if(UIDevice.currentDevice().userInterfaceIdiom == .Phone){

  }

o
odemolliens

Swift 3.0:

let userInterface = UIDevice.current.userInterfaceIdiom

if(userInterface == .pad){
    //iPads
}else if(userInterface == .phone){
    //iPhone
}else if(userInterface == .carPlay){
    //CarPlay
}else if(userInterface == .tv){
    //AppleTV
}

a
aBikis

Made a couple of additions to the above answers so that you get returned a type instead of string value.

I figured that this is primarily going to be used for UI adjustments so I didn't think it relevant to include all the sub models i.e. iPhone 5s but this could be easily extended by adding in model tests to the isDevice Array

Tested working in Swift 3.1 Xcode 8.3.2 with physical and simulator devices

Implementation:

UIDevice.whichDevice()

public enum SVNDevice {
  case isiPhone4, isIphone5, isIphone6or7, isIphone6por7p, isIphone, isIpad, isIpadPro
}

extension UIDevice {
  class func whichDevice() -> SVNDevice? {
    let isDevice = { (comparision: Array<(Bool, SVNDevice)>) -> SVNDevice? in
      var device: SVNDevice?
      comparision.forEach({
        device = $0.0 ? $0.1 : device
      })
      return device
    }

    return isDevice([
      (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0, SVNDevice.isiPhone4),
      (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0, SVNDevice.isIphone5),
      (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0, SVNDevice.isIphone6or7),
      (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0, SVNDevice.isIphone6por7p),
      (UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0, SVNDevice.isIpad),
      (UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0, SVNDevice.isIpadPro)])
  }
}



private struct ScreenSize {
  static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
  static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
  static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
  static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}

I've created a framework called SVNBootstaper which includes this and some other helper protocols, it's public and available through Carthage.


A
Andre Goncalves

You can use the new way on Swift 5:

switch traitCollection.userInterfaceIdiom {
        
    case .unspecified:
        // do something
    case .phone:
        // do something
    case .pad:
        // do something
    case .tv:
        // do something
    case .carPlay:
        // do something
    case .mac:
        // do something
    @unknown default:
        // do something
}

This is not new in Swift 5, and has already been posted, here for example.