Detect if the device is iPhone X

My iOS app uses a custom height for the UINavigationBar which leads to some problems on the new iPhone X.

Does someone already know how to reliable detect programmatically (in Objectiv-C) if an app is running on iPhone X?

  • How to check whether session live or expired in Quickblox iOS SDK?
  • Calling popToRootViewControllerAnimated after dismissModalViewControllerAnimated
  • Restore Purchase : Non-Consumable
  • Is garbage collection supported for iPhone applications?
  • How to get UIKeyboard size with Apple iPhone SDK
  • Handling applicationDidBecomeActive - “How can a view controller respond to the app becoming Active?”
  • EDIT:

    Of course checking the screens size is possible, however I wonder if there is some “build in” method like TARGET_OS_IPHONE to detect iOS…

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        CGSize screenSize = [[UIScreen mainScreen] bounds].size;
        if (screenSize.height == 812)
            NSLog(@"iPhone X");
    }
    

    EDIT 2:

    I do not think, that my question is an duplicate of the linked question. Of course there are methods to “measure” different properties of the current device and to use the results to decide which device is used. However this was not the actual point of my question as I tried to emphasize in my first edit.

    The actual question is: “Is it possible to directly detect if current device is an iPhone X (e.g. by some SDK feature) or do I have to use indirect measurements”?

    By the answers given so far, I assume that the answer is “No, there is not direct methods. Measurements are the way to go”.

    10 Solutions Collect From Internet About “Detect if the device is iPhone X”

    based on your question answer is No, there is not direct methods, for more information you can get the information from here

    if you want to detect the iphone X height use 2436px

    Device Screen Sizes and Orientations

    enter image description here

    swift 3 and above

    if UIDevice().userInterfaceIdiom == .phone {
            switch UIScreen.main.nativeBounds.height {
            case 480:
                print("iPhone Classic")
            case 960:
                print("iPhone 4 or 4S")
            case 1136:
                print("iPhone 5 or 5S or 5C")
            case 1334:
                print("iPhone 6 or 6S")
            case 2208:
                print("iPhone 6+ or 6S+")
            case 2436:
                print("iPhone X")
            default:
                print("unknown")
            }
        }
    

    objective C

        if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone) {
    
            switch ((int)[[UIScreen mainScreen] nativeBounds].size.height) {
                case 480:
                    printf("iPhone Classic");
                    break;
                case 960:
                    printf("iPhone 4 or 4S");
                    break;
                case 1136:
                    printf("iPhone 5 or 5S or 5C");
                    break;
                case 1334:
                    printf("iPhone 6 or 6S");
                    break;
                case 2208:
                    printf("iPhone 6+ or 6S+");
                    break;
                case 2436:
                    printf("iPhone X");
                    break;
                default:
                    printf("unknown");
            }
        }
    

    based on your question as follow

    or use screenSize.height as float 812.0f not int 812

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        CGSize screenSize = [[UIScreen mainScreen] bounds].size;
        if (screenSize.height == 812.0f)
            NSLog(@"iPhone X");
    }
    

    for more information you can get here

    UPDATE

    DO NOT use the userInterfaceIdiom property to identify the device type, as the apple documentation explains,

    For universal applications, you can use this property to tailor the behavior of your application for a specific type of device. For example, iPhone and iPad devices have different screen sizes, so you might want to create different views and controls based on the type of the current device.

    That is, this property is just used to identify the running app’s view style. However, the iPhone app (not the universal) could be installed in iPad device via App store, in that case, the userInterfaceIdiom will return the UIUserInterfaceIdiomPhone, too.

    The right way is to get the machine name via uname, check this thread for detail.

    Another possibility, which works currently because the iPhone X is the only one with a notch at the top. That is what I am really detecting here:

        iphoneX = NO;
        if (@available(iOS 11.0, *)) {
            if (_window.safeAreaInsets.top > 0.0) {
                iphoneX = YES;
            }
        }
    

    And of course, you might need to check the left and right safe area insets if you are in landscape orientation.

    Edit: _window is the UIWindow of the AppDelegate, where this check is done in application didFinishLaunchingWithOptions.

    Yes, it is possible.
    Download the UIDevice-Hardware extension (or install via CocoaPod ‘UIDevice-Hardware’) and then use:

    NSString* modelID = [[[UIDevice currentDevice] modelIdentifier];
    BOOL isIphoneX = [modelID isEqualToString:@"iPhone10,5"];
    

    Note that this won’t work in the Simulator, only on the actual device.

    All of these answers based on dimensions are susceptible to incorrect behavior on future devices. They’ll work today, but what if there’s an iPhone next year that’s the same size but has the camera, etc. under the glass so there’s no “notch?” If the only option is to update the app, then it’s a poor solution for you and your customers.

    You can also check the hardware model string like “iPhone10,1”, but that’s problematic because sometimes Apple releases different model numbers for different carriers around the world.

    The correct approach is to redesign the top layout, or solve the problems you’re having with the custom navigation bar height (that’s what I’d focus on). But, if you decide not to do either of those things, realize that whatever you’re doing is a hack to get this to work today, and you’ll need to correct it at some point, perhaps multiple times, to keep the hacks working.

    You should not assume that the only device that Apple releases with a different UINavigationBar height will be the iPhone X. Try to solve this problem using a more generic solution. If you want the bar to always be 20px bigger than its default height, your code should add 20px to the height of the bar, instead of setting it to 64px (44px + 20px).

    Check the device model / machine name, DO NOT use the point/pixel count in your code directly, it’s hard code!

    #import <sys/utsname.h> // import it in your header or implementation file.
    
    NSString* deviceName()
    {
        struct utsname systemInfo;
        uname(&systemInfo);
    
        return [NSString stringWithCString:systemInfo.machine
                              encoding:NSUTF8StringEncoding];
    }
    

    Result:

    @"iPhone10,3" on iPhone X (CDMA)
    @"iPhone10,6" on iPhone X (GSM)
    

    Refer to this answer.

    #define IS_IPHONE        (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    #define IS_IPHONE_4      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 480.0)
    #define IS_IPHONE_5      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
    #define IS_IPHONE_6      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
    #define IS_IPHONE_6PLUS  (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
    #define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
    #define IS_IPHONE_X      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 812.0)
    #define IS_RETINA        ([[UIScreen mainScreen] scale] == 2.0)
    
    #define IS_IPAD_DEVICE   [(NSString*)[UIDevice currentDevice].model hasPrefix:@"iPad"]
    
    #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    #define IS_IPHONE_X (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 812.0f)
    

    You can do like this to detect iPhone X device.

    if UIDevice().userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height == 2436 {
       //iPhone X
    }
    

    enter image description here

    According the @saswanb’s response, this is a Swift 4 version :

    var iphoneX = false
    if #available(iOS 11.0, *) {
        if ((UIApplication.shared.keyWindow?.safeAreaInsets.top)! > CGFloat(0.0)) {
            iphoneX = true
        }
    }