Detect if device is iOS
Asked Answered
D

23

578

I'm wondering if it's possible to detect whether a browser is running on iOS, similar to how you can feature detect with Modernizr (although this is obviously device detection rather than feature detection).

Normally I would favour feature detection instead, but I need to find out whether a device is iOS because of the way they handle videos as per this question YouTube API not working with iPad / iPhone / non-Flash device

Dittography answered 27/1, 2012 at 19:2 Comment(5)
See [What is the iOS 5 user-agent string?][1] (duplicate?). [1]: #7826373Adhesive
Is this client-side or server-side detection?Sterrett
Hey @DouglasGreenshields, it is client-sideDittography
Also, not a duplicate, I'm asking how to do it. I've never used user-agent sniffing before.Dittography
#19878424Fricke
G
1084

Detecting iOS

With iOS 13 iPad both User agent and platform strings are changed and differentiating between iPad and MacOS seems possible, so all answers below needs to take that into account now.

This might be the shortest alternative that also covers iOS 13:

function iOS() {
  return [
    'iPad Simulator',
    'iPhone Simulator',
    'iPod Simulator',
    'iPad',
    'iPhone',
    'iPod'
  ].includes(navigator.platform)
  // iPad on iOS 13 detection
  || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
}

iOS will be either true or false

Worse option: User agent sniffing

User Agent sniffing is more dangerous and problems appear often.

On iPad iOS 13, the user agent is identical with that of a MacOS 13 computer, but if you ignore iPads this might work still for a while:

var iOS = !window.MSStream && /iPad|iPhone|iPod/.test(navigator.userAgent); // fails on iPad iOS 13

The !window.MSStream is to not incorrectly detect IE11, see here and here.

Note: Both navigator.userAgent and navigator.platform can be faked by the user or a browser extension.

Browser extensions to change userAgent or platform exist because websites use too heavy-handed detection and often disable some features even if the user's browser would otherwise be able to use that feature.

To de-escalate this conflict with users it's recommended to detect specifically for each case the exact features that your website needs. Then when the user gets a browser with the needed feature it will already work without additional code changes.

Detecting iOS version

The most common way of detecting the iOS version is by parsing it from the User Agent string. But there is also feature detection inference*;

We know for a fact that history API was introduced in iOS4 - matchMedia API in iOS5 - webAudio API in iOS6 - WebSpeech API in iOS7 and so on.

Note: The following code is not reliable and will break if any of these HTML5 features is deprecated in a newer iOS version. You have been warned!

function iOSversion() {

  if (iOS) { // <-- Use the one here above
    if (window.indexedDB) { return 'iOS 8 and up'; }
    if (window.SpeechSynthesisUtterance) { return 'iOS 7'; }
    if (window.webkitAudioContext) { return 'iOS 6'; }
    if (window.matchMedia) { return 'iOS 5'; }
    if (window.history && 'pushState' in window.history) { return 'iOS 4'; }
    return 'iOS 3 or earlier';
  }

  return 'Not an iOS device';
}
Goad answered 27/1, 2012 at 20:51 Comment(35)
Thanks Pierre - this code seems simpler though, I just wonder whether I can just specify 'iOS' rather than having to type out all the separate iDevices.... if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) { // Do something }Dittography
As far as i know there aren't any properties that include the word iOS. I however simplified the regex (but still, device names are needed).Goad
navigator.appVersion is the browser version not the iOS version! w3schools.com/jsref/prop_nav_appversion.aspMagnificat
document.write("Browser Version: " + navigator.appVersion) It's the browser version and not the iOS version.Magnificat
What you're doing in the second snippet is feature inference, not feature detection. Feature detection is testing features that you're actually going to use, whereas what you're doing is testing features that you happen to know were introduced in a particular version of the OS and inferring the OS version from them. This is fragile because future versions of iOS could remove these features.Yeager
@Goad also parsing iOS ins't all safe, the older versions of iOS >4 was refered as iPhoneOS including on the iPadNoel
..interestingly, just across a userAgent string like Tiphone T67/1.0 Browser/wap2.0 Sync/SyncClient1.1 Profile/MIDP-2.0 Configuration/CLDC-1.1 ..Incapacitate
This is a better way to write your check: var iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);Fondness
Just a note - the navigator.platform array doesn't work on the iPad Simulator because it has the entire phrase "iPad Simulator" in the platform string.Kinzer
Testing for iPad, iPhone or iPod in the user agent string will give a false positive in case the user has a Window Phone. Internet Explorer on this device contains a message '...like iPhone OS...' in the user agent string and thus will return true on this test.Natal
This is much better var iOS = /(iP*)/g.test(navigator.userAgent);Gailgaile
Why aren't you a fan of User Agent sniffing?Holocrine
Simplest answer: var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent);Mccormac
Is there a way to infer iOS 9 yet?Hertha
@Dzh well in theory you can. It looks like iOS 9 will support forceTouch events.. If so, then you can try and test 'webkitmouseforcechanged' in document;.. I don't have access to it yet, so if you are able to test this code let me know to update my answer.Goad
@Goad good idea, but I wonder whether that will only detect iPhone 6S (as I would expect force touch events will only be available on the devices that support them)?Hertha
@Goad your code is superb (truely; respect) and I rolled it into some other detection code i've been using in prod, resulting in a great/lightweight gist for modern UI/UX control - isMobile, isTablet, isIE, isIOS -gist.github.com/gdibble/df3fd4016e632344336f3227a6f159e6Bloomfield
On a Mac mini I have this string (maybe is helpful for someone that needs to upgrade the regex): navigator.userAgent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"Lacto
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; - this might not work when minifying your js. Use this instead - var iOS = new RegExp("/iPad|iPhone|iPod/").test(navigator.userAgent) && !window.MSStream;Costly
@Goad @Dan navigator.platform is not deprecated, it's just not recommended to rely on it.Mauri
You are not checking whether it's an iOS device, but whether the device is either an iPhone, iPod or an iPad. If a new device with iOS were to be created, or if an Apple device is running another OS, then this will obviously not work. It's like detecting Windows by checking if the device is Microsoft Surface.Boy
From iOS 13 the iPad's user agent has changed to "Mac OS", 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 so this answer need to be updatedLimon
Not working for iOS 13. navigator.userAgent returns value of indexOf("ipad") as -1;Pouncey
platform not deprecated (no red border) and less messy than userAgent. You can use navigator.platform.indexOf('iP')>=0 or navigator.userAgent.indexOf("(iP")>=0 which seemed to cover 99% of cases (googled useragent and platform strings). And nobody develops to be compatible with 100% of all browsers anyway.Booster
@paul-rumkin Your last edit makes it NOT work for iOS 13 iPads. Please see the links right above what you edited.Booster
@PaulRumkin thanks, but there were more necessary fixes in my rejected edit. Please at least fix this inconsistency: function iOS() (from someone elses edit) but then follows iOS will be either true or false (from original author). Also, the edit that changed from var to function forgot to change the text above the edit from the shortest alternative to something like the most easy to read and editBooster
Finally, this bit if (iOS) { // <-- Use the one here above feels a bit off in general. It is supposed to reuse whatever is your final decision on the topmost recommended approach. I think var is better than function for the topmost. Or reformat to allow it to run, emit a boolean, and garbage collect itself. And same applies to the lowermost function - no need to rerun it, so no need to have it as a function.Booster
@gcharita The edit you rejected yesterday was to fix two glaring bugs in the answer. Please can you fix the bug instead? I've tried and gotten rejected. Otherwise I can try hunting down the original author on social media perhaps. I just want this to be not wrong.Booster
This bit (navigator.userAgent.includes("Mac") && "ontouchend" in document) as recommended both here and elsewhere on StackOverflow page is no longer enough, since it returns true on Chrome 85 on a non touch device. Tacking on && navigator.maxTouchPoints > 2 seems like a good enough stop-gap fix for now.Booster
navigator.platform is now deprecated, so I'm searching for the replacement technique to no avail. developer.mozilla.org/en-US/docs/Web/API/Navigator/platformStream
yes navigator.platform is deprecated, yet still supported by all relevant browsers and its replacement "navigator.userAgentData.platform" is useless because in most browsers it returns just empty string or it is undefined as of 1st November 2021Criterion
@Goad any replacement for navigator.platform ?Gules
This might be a good backwards compatible way to get the platform. const platform = navigator.userAgentData?.platform || navigator.platform;Vimineous
In IPadOS 16 (maybe earlier) there is a setting (Settings -> Safari -> Request Desktop Website) when enabled it removes any device name like 'IPad' or 'IPhone' from the useragent. Could be the reason for an indentical useragent like a Mac ones. @LimonKabyle
Use swiftpackageindex.com/YogeshJethava/User_Agent_iOS to find DarwinVersion, CFNetworkVersion, deviceVersion, deviceName, appNameAndVersionObovate
F
70

After iOS 13 you should detect iOS devices like this, since iPad will not be detected as iOS devices by old ways (due to new "desktop" options, enabled by default):

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

The first condition for iOS < 13 or iPhone or iPad with disabled Desktop mode, the second condition for iPadOS 13 in the default configuration, since it position itself like Macintosh Intel, but actually is the only Macintosh with multi-touch.

Rather a hack than a real solution, but work reliably for me

P.S. As being said earlier, you probably should add IE checkup

let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream
Ferland answered 23/9, 2019 at 15:3 Comment(8)
Why not use the navigator.userAgent for this check /iPad|iPhone|iPod/.test(navigator.platform)? It seems that navigator.platform always returns 'MacIntel' for iPhone iOS <= 12Motmot
@CharisTheo Because iPad is not in the userAgent in iOS >= 13Beetroot
but you are already checking for iPad iOS >= 13 in the second check or am I missing something?Motmot
navigator.maxTouchPoints isn't supported in iOS, so that check isn't going to do anything for you.Wisteria
@PaulC, You are correct in that maxTouchPoints is undefined for iOS 12 and below, but kikiwora is on the right track since maxTouchPoints is supported in iOS 13. See my answer.Shamefaced
Curious if there is a similar PHP version of this? Can PHP handle the maxTouchPoints?Domenic
@Domenic I know not enough about PHP to be sure, but isn't it used for server-side logic? As far as I know, PHP was never executed in browsers. Thus, it would have no way to detect a page's runtime properties, only those that are passed during requests. Furthermore, the server should not ever know about the view layer, that's a responsibility of view, in our case - the page itself, not of a server that forms that page. Again, I may be mistaken about PHP, since I have had very limited experience with it.Ferland
@Ferland navigator.platform is deprecated, any other alternative? 😢Gules
S
22

None of the previous answers here work for all major browsers on all versions of iOS, including iOS 13. Here is a solution that works for Safari, Chrome and Firefox for all iOS versions:

var isIOS = (function () {
    var iosQuirkPresent = function () {
        var audio = new Audio();

        audio.volume = 0.5;
        return audio.volume === 1;   // volume cannot be changed from "1" on iOS 12 and below
    };

    var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
    var isAppleDevice = navigator.userAgent.includes('Macintosh');
    var isTouchScreen = navigator.maxTouchPoints >= 1;   // true for iOS 13 (and hopefully beyond)

    return isIOS || (isAppleDevice && (isTouchScreen || iosQuirkPresent()));
})();

Note that this code snippet was written with priority on readability, not conciseness or performance.

Explanation:

  • If the user agent contains any of "iPod|iPhone|iPad" then clearly the device is iOS. Otherwise, continue...

  • Any other user agent that does not contain "Macintosh" is not an Apple device and therefore cannot be iOS. Otherwise, it is an Apple device, so continue...

  • If maxTouchPoints has a value of 1 or greater then the Apple device has a touch screen and therefore must be iOS since there are no Macs with touch screens (kudos to kikiwora for mentioning maxTouchPoints). Note that maxTouchPoints is undefined for iOS 12 and below, so we need a different solution for that scenario...

  • iOS 12 and below has a quirk that does not exist in Mac OS. The quirk is that the volume property of an Audio element cannot be successfully set to any value other than 1. This is because Apple does not allow volume changes on the Audio element for iOS devices, but does for Mac OS. That quirk can be used as the final fallback method for distinguishing an iOS device from a Mac OS device.

Shamefaced answered 29/5, 2020 at 21:20 Comment(5)
It seems like this will have the side effect of actually changing the audio volume on non-iOS devices (in case that's important to anyone)Horizontal
@Tspoon, The provided code snippet creates a throw-away Audio element (if necessary). The element is not actually used to play sound in this case, and it does not affect the volume of other Audio elements you might employ in your system.Shamefaced
the volume hack doesn't work - it returns 0.5 and then some thread in webkit resets it back to 1 at some point in the future.Offcolor
@Sean, Were you careful to test on an old iPad running iOS 12 or below? I just retested on an old iPad running iOS 12.5.7 (latest version available for that model iPad as of this writing), and confirmed that the Audio element's volume setting still cannot be changed in iOS 12 (I checked the value immediately following the assignment). However, I also noticed that iOS 12 now includes "iPad" in the user agent, so testing for the quirk is now longer needed for old iPads, at least those that are being updated. Either way, the snippet I originally provided continues to work as intended.Shamefaced
@BobArlof I do have an oldish ipad but it's running 15.7.3 In my tests it momentarily sets the volume to say 0.5 and then about 0.1s later resets it to 1 again. I just did some user agent sniffing to detect it and block our volume controls. I dunno why Apple do these things...!Offcolor
N
19

This sets the variable _iOSDevice to true or false

_iOSDevice = !!navigator.platform.match(/iPhone|iPod|iPad/);
Noel answered 8/8, 2013 at 19:3 Comment(4)
what does !! do?Edelmiraedelson
@astronought double negation is used to cast to a booleanNoel
@astronought bang bang, you're boolean :DVehicular
Using /iPhone|iPod|iPad/.test(navigator.platform) you can avoid the !!Treadmill
E
11

UPDATE: My original answer doesn't cover iPad in desktop mode (the default changes to desktop mode in upcoming iPadOS 13 and higher).
That's fine for my usecases, if it's not for you, use this update:

// iPhone and iPad including iPadOS 13+ regardless of desktop mode settings

iOSiPadOS = /^iP/.test(navigator.platform) ||
           /^Mac/.test(navigator.platform) && navigator.maxTouchPoints > 4;
  • This should be safe as long as
    • desktop Macs don't support touch events at all
    • or not more than 4 touch points (current iOS devices support 5 touch points)
  • It's fast because the regexp ^ first checks the starting position of the platform string and stops if there is no "iP" (faster than searching the long UA string until the end anyway)
  • It's safer than navigator.userAgent check as navigator.platform is much less likely faked
  • Detects iPhone / iPad Simulator

ORIGINAL ANSWER:
Wow, a lot of longish tricky code here. Keep it simple, please!

This one is IMHO fast, save, and working well:

 iOS = /^iP/.test(navigator.platform);

  // or, if you prefer it verbose:
 iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform);
Empedocles answered 21/9, 2018 at 17:55 Comment(4)
iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform); rather than this i would do iOS = /^(iPhone|iPad|iPod)/.test(navigator.userAgent || navigator.vendor || navigator.platform); as a fallback measure cuz in my case navigator.platform didn't work, but doing it like later worked fineKheda
navigator.platform didn't work? Are you really on iOS then?. Check with jeka.info/test/navigator.html . userAgent gives false positives because some vendors fake it to mimic Apple devices for whatever reasons. vendor just returns either Google Inc., Apple Computer, Inc., or nothing (in Firefox).Empedocles
navigator.platform is being discouraged: "[it] should almost always be avoided in favor of feature detection."Alcatraz
@A-TECH: this is is The Remaining of the "almost always" case. Example (stupid): All iOS devices have Zapf's "Optima" font installed. For some reasons you want to know if that font is available. Please giive me some feature-detecting code for this usecase!Empedocles
G
10

If you are using Modernizr, you can add a custom test for it.

It doesn't matter which detection mode you decide to use (userAgent, navigator.vendor or navigator.platform), you can always wrap it up for a easier use later.

//Add Modernizr test
Modernizr.addTest('isios', function() {
    return navigator.userAgent.match(/(iPad|iPhone|iPod)/g);
});

//usage
if (Modernizr.isios) {
    //this adds ios class to body
    Modernizr.prefixed('ios');
} else {
    //this adds notios class to body
    Modernizr.prefixed('notios');
}
Gaven answered 27/5, 2013 at 8:18 Comment(2)
Be carefull, Modernizr automatically lowercase the name of the added test. (in your example, Modernizr.isiOS will never return true). Bad behavior of the lib in my view ...Almshouse
Just tiny notice: you can simplify return x ? true : false to return Boolean(x) or just return !!xAgretha
W
8

A simplified, easy to extend version.

var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;
Waldron answered 18/3, 2014 at 0:20 Comment(3)
If you also want this to work on iOS Simulator you can use: navigator.platform.replace(' Simulator', '').Escapement
But it doesn't work, cause ['str'].indexOf('string') == -1Agretha
navigator.platform will be exactly 'iPad', 'iPhone' or 'iPod' unless the simulator is running.Waldron
B
6

Detecting iOS (both <12, and 13+)

Community wiki, as edit queue says it is full and all other answers are currently outdated or incomplete.

const iOS_1to12 = /iPad|iPhone|iPod/.test(navigator.platform);

const iOS13_iPad = (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));

const iOS1to12quirk = function() {
  var audio = new Audio(); // temporary Audio object
  audio.volume = 0.5; // has no effect on iOS <= 12
  return audio.volume === 1;
};

const isIOS = !window.MSStream && (iOS_1to12 || iOS13_iPad || iOS1to12quirk());
Booster answered 27/1, 2012 at 19:2 Comment(1)
'platform' is deprecated nowHedve
I
4

It's probably worth answering that iPads running iOS 13 will have navigator.platform set to MacIntel, which means you'll need to find another way to detect iPadOS devices.

Indifferent answered 21/7, 2019 at 14:53 Comment(0)
G
2

I wrote this a couple years ago but i believe it still works:

if(navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPhone/i) || (navigator.userAgent.match(/iPod/i))) 

    {

        alert("Ipod or Iphone");

    }

else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPad/i))  

    {

        alert("Ipad");

    }

else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.indexOf('Safari') != -1)

    {

        alert("Safari");

    }

else if (navigator.vendor == null || navigator.vendor != null)

    {

        alert("Not Apple Based Browser");

    }
Gezira answered 5/12, 2012 at 4:24 Comment(0)
S
2

Wherever possible when adding Modernizr tests you should add a test for a feature, rather than a device or operating system. There's nothing wrong with adding ten tests all testing for iPhone if that's what it takes. Some things just can't be feature detected.

    Modernizr.addTest('inpagevideo', function ()
    {
        return navigator.userAgent.match(/(iPhone|iPod)/g) ? false : true;
    });

For instance on the iPhone (not the iPad) video cannot be played inline on a webpage, it opens up full screen. So I created a test 'no-inpage-video'

You can then use this in css (Modernizr adds a class .no-inpagevideo to the <html> tag if the test fails)

.no-inpagevideo video.product-video 
{
     display: none;
}

This will hide the video on iPhone (what I'm actually doing in this case is showing an alternative image with an onclick to play the video - I just don't want the default video player and play button to show).

Stheno answered 10/5, 2014 at 19:23 Comment(1)
iOS10 now allows for playsinline so you can use 'playsInline' in document.createElement('video'); as a test now github.com/Modernizr/Modernizr/issues/2077Stheno
S
2

If you're using React, There is great library for this kind of issues: REACT-UGENT. (Built with ua-parser-js.)

https://github.com/medipass/react-ugent

Available browsers are:

chrome, chromium, edge, firefox, ie, lynx, safari, opera

Available OS are:

android, blackberry, chromium os, debian, ios, linux, mac os, ubuntu, unix, windows

Available devices are:

console, computer, mobile, tablet, smarttv, wearable, embedded

Easy to use as:

<Ugent browser="safari" os="ios">
  <div>
    This text only shows on Safari on iOS.
  </div>
</Ugent>

If you're not using React, basically, you can use - ua-parser-js

https://github.com/faisalman/ua-parser-js

Strigil answered 14/9, 2021 at 12:30 Comment(0)
N
2

If you are still trying to check if is iOS or not, I recommend you to use this approach:

  1. Create a folder called helper
  2. Create a file called platform.ts or platform.js
  3. Export the function isIOS:
export const isIOS = () => {
    let platform = navigator?.userAgent || navigator?.platform || 'unknown'

    return /iPhone|iPod|iPad/.test(platform)
}

The result will be true if is an iPhone or iPod or Ipad or it will be false otherwise.

You may ask, why do I need to check navigator.userAgent || navigator.platform, well the reason is simple the second option used to be the default one but now it is deprecated and some browsers will stop supporting this in the future, the first one is more reliable.

You can check here about the deprecation that I mentioned above:

https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#:~:text=Deprecated%3A%20This%20feature%20is%20no,be%20kept%20for%20compatibility%20purposes.

Logging the userAgentData, userAgent and platform.

Using the function below, I received these logs:

    console.log({
        userAgentData: navigator?.userAgentData?.platform,
        userAgent: navigator?.userAgent,
        platform: navigator?.platform,
    })

    {
        "userAgentData": "",
        "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
        "platform": "MacIntel"
    }

I was testing it on my Macbook and it worked on different browsers and operation systems. So, as you can see navigator?.userAgentData?.platform will not work at all.

I also didn't receive any errors related to my typescript, even though that I am using React to call this function.

Bonus, isAndroid

If you wondering how to check if is an Android platform, I suggest you don't follow the idea of doing the opposite of isIOS as:

const isAndroid = !isIOS();

The reason is quite simple, it will not work since desktops will be recognized as an Android platform. To solve this problem you just need to do this check:

export const isAndroid = () => {
    const ua = navigator.userAgent.toLowerCase() + navigator?.platform.toLowerCase();
    const isAndroid = ua.indexOf("android") > -1;

    return isAndroid;
}

The reason why we are checking navigator.userAgent plus navigator?.platform is to support old browsers and the new ones.

Nanoid answered 9/10, 2022 at 9:40 Comment(2)
Will it be safe to remove navigator?.platform if that is going to be removed in future and only rely on navigator?.userAgent?Democratic
Since this will be removed it means the result will be undefined but since we also want to target old browsers just in case, it makes sense to add it there.Nanoid
B
1

The user-agents on iOS devices say iPhone or iPad in them. I just filter based on those keywords.

Breuer answered 27/1, 2012 at 19:6 Comment(3)
There's also iPod Touches to consider.Sterrett
@DouglasGreenshields Correct. Forgot about that one but I believe it transmits its identity in the user-agent, as well.Breuer
User agent of iPad safari will no longer include "iPad" from iPadOS 13.Hahnke
D
1

There is no need to test navigator.userAgent or navigator.platform:

const isIOS = typeof navigator.standalone === 'boolean';

navigator.standalone is only set on iOS Safari. See MDN, Safari HTML Reference.

Doorplate answered 18/6, 2021 at 9:45 Comment(6)
What if the browser is chrome?Lanita
@Lanita just tried and it returns "undefined" on iOs chrome. So this answer is not correctCriterion
@Lanita I just tried this on Firefox 38.1 on iPhone (iOS 14.3) and Chrome 95.0.4638.50 on iPad (iPadOS 15.0.2) and it worked on bothDoorplate
@Criterion are you sure you typed the code correctly?Doorplate
Using the const in @JefferyTo's example above worked well for me with this conditional check: if (isIOS === true ) { //stuff for iOS } else {// stuff for all other }Ensphere
'platform' is deprecatedHedve
A
1

Make use of Apple Pay JS API checks

`if (window.dw && window.dw.applepay && window.ApplePaySession && window.ApplePaySession.canMakePayments()) {

// do the needful

}`

Aundreaaunson answered 19/9, 2023 at 10:25 Comment(0)
N
0

Because navigator.platform is deprecated and it is better to not use it anymore, I want to add an other solution.

You can filter on MacOS systems by checking the navigator.vendor. When the outcome is Apple Computer, Inc., you know it is MacOS.

Nystrom answered 16/11, 2021 at 18:4 Comment(1)
navigator.vendor is deprecated as wellCorporeity
U
0

For anyone looking to be compliant with PageSpeed Insights and Lighthouse best practices which flags "issues" found in the console for the use of navigator.userAgent (etc), this can help you (I gleaned this from Boostrap 5):

function getUAString() {
    let uaData = navigator.userAgentData;
    if (null !== uaData && uaData.brands) {
        return uaData.brands.map(item => item.brand + '/' + item.version).join(' ');
    }
    return navigator.userAgent;
}

const isIOS = /iP(hone|od|ad)/.test(getUAString());
Unreflecting answered 21/5, 2023 at 23:37 Comment(0)
E
0

this was my solution after suffering a lot its not perfect but hope to help someone, I have tried it and it’s and it exactly target iPad safari.

function detectSafariOnIpadOS() {
  var userAgent = navigator.userAgent;
  var isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
  var isIpad = /iPad/i.test(userAgent);
  var isMacintosh = /Macintosh/i.test(userAgent);
  var isTouchDevice = "ontouchend" in document;

  console.log("User Agent:", userAgent);
  console.log("detectSafariOnIpadOS result:", isSafari && (isIpad || (isMacintosh && isTouchDevice)));

return isSafari && (isIpad || (isMacintosh && isTouchDevice));
}
Engelbert answered 1/9, 2023 at 20:52 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Porch
P
-1

You can also use includes

  const isApple = ['iPhone', 'iPad', 'iPod', 'iPad Simulator', 'iPhone Simulator', 'iPod Simulator',].includes(navigator.platform)
Pandolfi answered 27/5, 2020 at 5:17 Comment(2)
This misses out on the the "... Simulator" variety. So many answers, so few well-researched :(Booster
platform is deprecated developer.mozilla.org/en-US/docs/Web/API/Navigator/platformGrubb
F
-2

In my case the user agent was not good enought since in the Ipad the user agent was the same as in Mac OS, therefore I had to do a nasty trick:

var mql = window.matchMedia("(orientation: landscape)");

/**
 * If we are in landscape but the height is bigger than width
 */
if(mql.matches && window.screen.height > window.screen.width) {
    // IOS
} else {
    // Mac OS
}
Ferine answered 4/5, 2020 at 10:40 Comment(0)
M
-3

In order to detect the iOS version, one has to destructure the user agent with a Javascript code like this:

 var res = navigator.userAgent.match(/; CPU.*OS (\d_\d)/);
    if(res) {
        var strVer = res[res.length-1];
        strVer = strVer.replace("_", ".");
        version = strVer * 1;
    }
Magnificat answered 19/2, 2012 at 16:5 Comment(0)
T
-3

var isiOSSafari = (navigator.userAgent.match(/like Mac OS X/i)) ? true: false;

Tbar answered 12/2, 2013 at 17:45 Comment(1)
This ternary operator is useless; test returns a boolean and can replace matchHogue

© 2022 - 2024 — McMap. All rights reserved.