How to detect device name in Safari on iOS 13 while it doesn't show the correct user agent?

26,097

Solution 1

Indeed, while option change in Settings may be a good solution for the user, as a developer you can't rely on that. It is as weird as to ask the user to not to use dark mode cause your app doesn't support it instead of opt-out of it using plist.

As for me, the most simple way to detect iOS / iPad OS device now:

let isIOS = /iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)

The first condition is old-fashioned and works with previous versions, while the second condition works for iPad OS 13 which now identifies itself as:

"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)"

which by all platform detectors I know is not detected (for now) neither as mobile nor desktop.

So since iPad OS now calls itself Macintosh, but real macs have no multi-touch support, this solution is ideal to detect iPad OS devices which are the only multi-touch "Macintosh" devices in existence.

P.S. Also, you may want to augment this checkup for IE exclusion from being detected as an iOS device

let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream

Solution 2

const isIOS = !!(/iPad|iPhone|iPod/.test(navigator.platform)
  || (navigator.platform === "MacIntel" && typeof navigator.standalone !== "undefined"))

As an alternative to the accepted answer, I found you can use the navigator.standalone param. It's non-standard and used only on iOS Safari at present:

Navigator.standalone

Returns a boolean indicating whether the browser is running in standalone mode. Available on Apple's iOS Safari only.

When combined with navigator.platform === "MacIntel" iPad's are the only devices that define this property, therefore typeof navigator.standalone !== "undefined" filters out Macs running Safari (touchscreen or not).

Share:
26,097
Admin
Author by

Admin

Updated on July 05, 2022

Comments

  • Admin
    Admin almost 2 years

    After Apple's iOS 13 release, I realized window.navigator.userAgent in Safari on iPad iOS 13 is same as on MacOS. Something like this:

    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

    As you see, it's a wrong user-agent for iPad and there is no way to detect if the current device is an iDevice.


    After an initial research, I found a workaround for it:

    Go to Settings -> Safari -> Request Desktop Website -> All websites. You notice "All websites" is enabled by default. If you disable it and get window.navigator.userAgent the correct user agent is now displayed.

    But I cannot ask each user to do this setting change for each device. So I tried to find another way and ended up by writing the following code which checks if it's Safari, macOS, and touch-screen then the device should be an apple mobile device, but I'm wondering is there any better suggestion/way to detect the correct device name in Safari iOS 13?

    detectOs = function(){
       //returns OS name, like "mac"
    };
    
    //is Safari on an apple touch-screen device
    isSafariInIdevice = function(){
       if (/Safari[\/\s](\d+\.\d+)/.test(windows.navigator.userAgent)) {
          return 'ontouchstart' in window && detectOs() === "mac";      
       }
       return false;
    };
    
  • newdeveloper
    newdeveloper over 4 years
    thanks that is useful for clientside. could you please help how to detect in razor syntax on server side when page is rendering. badly stuck with this problem. stackoverflow.com/questions/58344491/…
  • kikiwora
    kikiwora over 4 years
    I’m not proficient with a razor, sorry 🤷🏻‍♂️ Also, I don’t think that’s possible on the server side since iPad sends Macintosh header to server - iPad now meant to work like desktop in web and we should not intervene in this behavior
  • Carson
    Carson over 4 years
    Seems a bit fragile for long-term use, but the only solution that works. Thanks!
  • Anke
    Anke over 4 years
    Has anyone had success with this in Safari? Mozilla says Safari doesn't support navigator.maxTouchPoints. developer.mozilla.org/en-US/docs/Web/API/Navigator/…
  • kikiwora
    kikiwora over 4 years
    This solution designed for Safari in the first place. It's weird that Mozilla site lists this JS method as unsupported in Safari. It definitely works on all of my Apple devices (laptop, tablet and phone) But indeed, the downside of this method is very fragile from a long-term use perspective. Especially if touch-enabled macs will be available. The thing is, as I said, that new Safari is meant to be like that - it was designed to be detected as a desktop to provide more features for users, since modern sites ofter not so functional mobile versions instead, forcing users to use them.
  • rassar
    rassar over 4 years
    Please provide some explanation for your answer.
  • Justin Putney
    Justin Putney over 4 years
    Wrong language entirely.
  • Roger Far
    Roger Far over 4 years
    This will detect an iPhone also as iPad as the deviceWidth > 750.
  • Csaba Toth
    Csaba Toth about 4 years
    Can this tell apart touch screen iBooks or IMacs or will this categorize them as isIOS as well? iBooks or iMacs are legitimately have Intel CPUs (not just a lie like the new iOS Safari), plus they are touch screen as well.
  • Csaba Toth
    Csaba Toth about 4 years
    @RogerFar I think that's less of a sacrifice than categorizing touch screen iBooks or iMacs as mobile devices. Seems like people are completely lost in the forest with this issue and since the Safari can lie now the only way to sort out the issue is to test for some feature like this snippet does. If you like you can add more code to test width and sophisticate it further as you like.
  • kikiwora
    kikiwora about 4 years
    @CsabaToth, try it yourself if you have such a device. As far as I know, there are no macOS computers with touchscreen provided by Apple. But maybe you can somehow connect a touch-capable display to operate macOS, even so, I have no idea if macOS provides Safari information about touchpoints count. But if it doesn’t, then yes, I’m afraid that this method will not be able to distinguish iOS and macOS with touchscreen apart from each other. But anyway, you’re not supposed to detect iOS devices anyway when the user wants a desktop version of a site. So it is designed that way intentionally.
  • Larry Flewwelling
    Larry Flewwelling about 4 years
    ios 12 does not support maxTouchPoints, but ios 13 does (safari) tested April 9, 2020
  • Michal Tsadok
    Michal Tsadok about 4 years
    @kikiwora - so does the P.S. should be used? in which condition IE will have similar userAgent? can you please elaborate on this?
  • kikiwora
    kikiwora about 4 years
    @MichalTsadok once upon a time Microsoft used sort of a hack, for no apparent reason to me, but we know it leads to some IEs (I don't know which versions exactly) being detected as iOS. And since some software uses IE as WebView substitute, it is also affected. There were no cases in my engineering life when that checkup was needed, so I did not study this issue fully. But the issue described is still quite possible in 2020. So my recommendation - just use that checkup, it can't break anything and removing it does not improve performance since the result of let is calculated only once
  • Thomas Kellough
    Thomas Kellough almost 4 years
    Thanks for this solution. This fixed what I needed it for. Although it's not the best long-term, it's a good bandaid fix until either Apple comes out with Touchscreen computers or they get their crap together and name their devices correctly!
  • kofifus
    kofifus over 3 years
    shouldn't it be isIpadSafari = ?
  • GuyC
    GuyC over 3 years
    @kofifus the first part of the OR condition tests for iPad//iPhone/iPod in the platform string. The second part is the iOS 13 iPad so it's not just looking for iPads running Safari
  • kikiwora
    kikiwora over 3 years
    ⚠️ Just as a notice - this code may become obsolete soon, since now we have an Apple Silicone-based Macs & a hint regarding Touch-base Macs has been found in the App Store animations, and even publicly displayed for some time.