Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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;
};
like image 687
Saeid Amanzadeh Avatar asked Sep 19 '19 22:09

Saeid Amanzadeh


People also ask

What is user agent in Safari develop?

The user agent is a string of text that your browser sends with each web page request. The user agent string is how web sites can identify which web browser and operating system you are using.


2 Answers

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
like image 134
kikiwora Avatar answered Oct 18 '22 18:10

kikiwora


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

like image 4
GuyC Avatar answered Oct 18 '22 19:10

GuyC