25

In iOS 13 apple changed the user-agent that iPad uses.

Instead of (for example)

Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10

it become (for example)

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

My question is how can we distinguish between iPad and mac now?

zvi
  • 3,677
  • 2
  • 30
  • 48
  • 2
    That's the point. You shouldn't. You should serve a desktop site to an iPad. – Paulw11 Jul 08 '19 at 12:44
  • @Paulw11 but I have a serivce that is supported only on iPad and not mac! – zvi Jul 08 '19 at 12:52
  • 3
    Well, an iPad is now a Mac as far as web sites are concerned – Paulw11 Jul 08 '19 at 13:07
  • 7
    Thanks but that’s not an answer to my question. – zvi Jul 09 '19 at 03:58
  • I understand that, I guess what I am saying is that barring any changes by Apple in subsequent betas is that you can no longer tell the difference between an iPad and a Mac from a web server; Apple don't want web servers to know. You might as well just support Macs since you already are; Changing user agent on Safari to look like an iPad is trivial. I guess you could try and examine the window size, but that is pretty unreliable, especially since iPadOS will support even more flexible windowing. If you really want iPad only, release an app – Paulw11 Jul 09 '19 at 04:15
  • 2
    Even I have same issue. I want to show download .dmg in case of it's Mac & redirect it to app store if its IPadOS. – Sahil Doshi Sep 12 '19 at 10:24
  • 1
    Possible duplicate of [Tell iPadOS from macOS on the web](https://stackoverflow.com/questions/56578799/tell-ipados-from-macos-on-the-web) – Eugene Berdnikov Sep 13 '19 at 17:52
  • 1
    See my comment here: https://stackoverflow.com/questions/57765958/how-to-detect-ipad-and-ipad-os-version-in-ios-13-and-up/57924983#57924983 – Justin Putney Nov 08 '19 at 00:30
  • @zvi Problem is, it still does not support all the features (like background-attachment: fixed). – nsoeth Nov 15 '19 at 09:48

3 Answers3

13

The condition I used to detect IpadOS:

ua.toLowerCase().indexOf('macintosh') > -1 && navigator.maxTouchPoints && navigator.maxTouchPoints > 2
quangh
  • 388
  • 4
  • 8
4

Unfortunately doing so via the User-Agent string alone doesn't seem to be possible anymore. This is a bit of an issue if you're server-side and need to share downloads differently as you mentioned in one of your comments.

However, the below should reliably detect iPads on the client-side:

const iPad = !!(navigator.userAgent.match(/(iPad)/)
  || (navigator.platform === "MacIntel" && typeof navigator.standalone !== "undefined"))

It avoids relying on touch events which will occur on Macs with touch screen monitors, and instead uses navigator.standalone which is an iOS only property.

GuyC
  • 6,494
  • 1
  • 31
  • 44
  • We did try this, but it did not work to display data to iPad (6th generation) using `navigator.standalone` as a filter. Will be doing some more tests with this solution as well as `const iPad = (userAgent.match(/(iPad)/) /* iOS pre 13 */ || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) /* iPad OS 13 */);`. – rhand May 10 '21 at 00:46
  • 1
    @rhand testing on Browserstack 6th Gen iPads it works as expected, the older gen versions are usually easier to detect as they contain the string iPad within navigator.userAgent - what browser are you testing in? – GuyC May 10 '21 at 04:43
  • Just using latest Safari 14.0.3. I think the issue may be that we load the check too late in our Vue file. We will need to do some more tests. Thanks for your feedback. – rhand May 10 '21 at 05:06
3

Combining quangh's answer and Michael Zaporozhets's answer to detect mobile devices including iPads.

detectMobile() {
  let isMobile = RegExp(/Android|webOS|iPhone|iPod|iPad/i)
   .test(navigator.userAgent);

  if (!isMobile) {
    const isMac = RegExp(/Macintosh/i).test(navigator.userAgent);

    if (isMac && navigator.maxTouchPoints && navigator.maxTouchPoints > 2) {
      isMobile = true;
    }
  }
  return isMobile;
}
BJax
  • 153
  • 9