How to Detect iPad and iPad Os Version in iOS 13 and Up

How to detect iPad Pro as iPad using javascript?

I guess that iPad Pro is upgraded to iPadOS 13 Beta. Since Apple claimed Desktop-Class Browsing with Safari on iPadOS, it seems mobile Safari also mimics macOS behavior and user agent.

So, the short answer is it's not possible.

However you can try workarounds from answers to this question.

PHP mobile detection with new iPadOS/iOS 13

Best I got as a solution was to use javascript:

// iPad check
if( (window.screen.height / window.screen.width == 1024 / 768) ||
(window.screen.height / window.screen.width == 1112 / 834) ||
(window.screen.height / window.screen.width == 1366 / 1024)
) {
// do stuff here
}

Not as perviously intended, but the best solution I have.

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

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

How to detect iOS 13 on JavaScript?

I would like to advice you against detecting operating system or browser from user agent, since they are susceptible to change more than an API for that does, till a reliable stable standard API lands. I have no idea about when this second part will happen.

However, I can suggest to detect feature instead if in this case it is applicable to you.

You can check if the anchor html element supports download attribute:

"download" in document.createElement("a") // true in supporting browsers false otherwise

That way you can display the appropriate html markup depending on the output for each case.
Something like that may help:

function doesAnchorSupportDownload() {
return "download" in document.createElement("a")
}
// or in a more generalized way:
function doesSupport(element, attribute) {
return attribute in document.createElement(element)
}

document.addEventListener("DOMContentLoaded", event => {
if (doesAnchorSupportDownload()) {
anchor.setAttribute("display", "inline"); // your anchor with download element. originally display was none. can also be set to another value other than none.
} else {
image.setAttribute("display", "inline"); // your alone image element. originally display was none. can also be set to another value other than none.
}
});

For example, I use following to detect if I am on an ar quick look supporting browser on iOS:

function doesSupportAnchorRelAR() {
return document.createElement("a").relList.supports("ar");
}

You can also use techniques documented below:
http://diveinto.html5doctor.com/detect.html#techniques

Is there a way to detect if extension is running on iPad vs iPhone

While figuring out macOS vs iOS is fairly simple through using browser.runtime.getPlatformInfo(), determining iOS vs iPadOS is more difficult.

When the extension popup comes up there are two different behaviors on Safari on iOS. On iPhone it comes up as a full screenwidth menu from the bottom of the screen. On iPad it behaves like Safari on MacOS and the popup comes down from the extension icon in the toolbar and is dynamically sized.

Keep in mind that on iPadOS the popup can also show up as it does on iOS when the browser is in split view. Because of this it's important to track window resize events and to test the popup in and out of split view, across all of the split view sizes.

The only complete solution I've found is using a combination of Swift, Javascript and CSS.

Swift side

In your WebExtension, or wherever you like, you could create a simple function that returns which platform you're on. I use this over browser.runtime.getPlatformInfo() since the latter can't discern iOS vs iPadOS. Something like:

func getPlatform() -> String {
var platform:String
#if os(iOS)
if UIDevice.current.userInterfaceIdiom == .pad {
platform = "ipados"
}
else {
platform = "ios"
}
#elseif os(macOS)
platform = "macos"
#endif
return platform
}

In order to communicate with the swift side of you application, you'll need to use native messaging from the javascript side - and put the appropriate message handlers on your swift side.

background.js


browser.runtime.sendNativeMessage({name: "getPlatformFromSwiftSide"}, response => {
if (response.platform === "ipados") {
...
} else if (response.platform === "ios") {
...
}
});

SafariWebExtensionHandler.swift

class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
func beginRequest(with context: NSExtensionContext) {
let item = context.inputItems[0] as? NSExtensionItem
let message = item?.userInfo?[SFExtensionMessageKey] as? [String: Any]
guard let name = message?["name"] as? String else {return}
let response = NSExtensionItem()
if name == "getPlatformFromSwiftSide" {
let platform = getPlatform()
response.userInfo = [SFExtensionMessageKey: ["platform": platform]]
}
context.completeRequest(returningItems: [response], completionHandler: nil)
}
}


At this point you can distinguish between iPadOS and iOS. However you still have the issue of whether or not the browser is in split view or not. As mentioned, for certain sizes in split view, the popup on iPadOS is laid out differently and you must account for this.

Currently I am unaware of any methods to easily determine this, outside of CSS media queries or Javascript matchMedia calls.

Further, calling window from the popup (or using media queries in the popup context) won't indicate the browser's size, but rather the popups. Since we wan't to know the browser size to determine how to size the popup, the only reliable way I know of accomplishing this is by using browser.tabs.sendMessage, send a message to the content script requesting the browser window size.


All of this seems more complicated than it need be, but I know of no other alternatives currently.

Detect if device is iOS

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';
}


Related Topics



Leave a reply



Submit