51Degrees shares updated JavaScript to enable device detection for Apple devices
Device Detection is among the best techniques available to optimise web sites for multi-screen. The power of the web server and the web browser are both utilised to deliver the most appropriate processes and screen layout for each device category. Most vendors recognise the importance of supporting this distinction between devices. Information about the model of the device is normally embedded into the data sent to websites (e.g. http headers). However, Apple do not fully support this approach for iPhones and iPads.
In 2015 we released a detailed blog on Device Detection for Apple iPhone and iPad.
Since then Apple have released several new iPhone models from the 6s to the new XS Max and XR. They have also released multiple new iPad models from the iPad 5 through to the new iPad Pros, including the new 11.0, and 12.9. Identifying these mobile devices can be challenging.
Because we endeavour to support companies and hobbyists with our unique open source approach, we are sharing the JavaScript code that will enable you to set up a ‘do it yourself’ internal solution. We would, of course, encourage you to consider saving yourself the time and effort required to maintain a device specification database. Wouldn’t it be easier to simply receive regular automated updates that you can plug into your existing analytics? The choice is yours!
How are you currently detecting iPhones or iPads?
Are you using a client-side JavaScript override or 51Degrees Device Detection solution?
If not, you will only get a result that states the device is either a mobile or desktop, or an iPhone or a Samsung as an example. But you will not get any more granular details such as screen size, OS or browser, for the device identified.
JavaScript code for detecting iPhones and iPads
Our preferred method to detect different Apple devices is to use the WEBGL_debug_renderer_info extension. The JavaScript code snippet shared below can run on clients browser, requires no external calls to any 3rd party sites. If you use 51Degrees solution it can be run server-side, allowing you the fastest detection possible.
The WEBGL_debug_renderer_info extension is part of the WebGL API and exposes two constants for debugging purposes, which are 1. vendor of the GPU and 2. the renderer name.
Depending on the privacy settings of the browser, this extension might only be available to privileged contexts. We have observed that it returns a result in approximately 90% of cases. Of course, this method is only possible as long as Apple don’t block this information in the future.
Here's the JavaScript code snippet for iPhones:
// iPhone model checks.
function getiPhoneModel() {
// Get renderer info from cavas.
var canvas = document.createElement("canvas");
if (canvas) {
var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (context) {
var info = context.getExtension("WEBGL_debug_renderer_info");
if (info) {
var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
}
}
}
var ratio = window.devicePixelRatio;
// iPhone XR, iPhone XS Max
if (window.screen.height / window.screen.width == 896 / 414) {
switch (ratio) {
default:
return "iPhone XR, iPhone XS Max";
case 2:
return "iPhone XR";
case 3:
return "iPhone XS Max";
}
}
// iPhone X, iPhone XS
else if (window.screen.height / window.screen.width == 812 / 375) {
switch (renderer) {
default:
return "iPhone X, iPhone XS";
case "Apple A11 GPU":
return "iPhone X";
case "Apple A12 GPU":
return "iPhone XS";
}
}
// iPhone 6+, iPhone 6s+, iPhone 7+, iPhone 8+
else if (window.screen.height / window.screen.width == 736 / 414) {
switch (renderer) {
default:
return "iPhone 6 Plus, 6s Plus, 7 Plus or 8 Plus";
case "Apple A8 GPU":
return "iPhone 6 Plus";
case "Apple A9 GPU":
return "iPhone 6s Plus";
case "Apple A10 GPU":
return "iPhone 7 Plus";
case "Apple A11 GPU":
return "iPhone 8 Plus";
}
}
// iPhone 6, iPhone 6s, iPhone 7, iPhone 8
else if (window.screen.height / window.screen.width == 667 / 375) {
if (ratio == 2) {
switch (renderer) {
default:
return "iPhone 6, 6s, 7 or 8";
case "Apple A8 GPU":
return "iPhone 6";
case "Apple A9 GPU":
return "iPhone 6s";
case "Apple A10 GPU":
return "iPhone 7";
case "Apple A11 GPU":
return "iPhone 8";
}
} else {
// or in zoom mode: iPhone 6+, iPhone 6S+, iPhone 7+, iPhone 8+
switch (renderer) {
default:
return "iPhone 6 Plus, 6s Plus , 7 Plus or 8 Plus (display zoom)";
case "Apple A8 GPU":
return "iPhone 6 Plus (display zoom)";
case "Apple A9 GPU":
return "iPhone 6s Plus (display zoom)";
case "Apple A10 GPU":
return "iPhone 7 Plus (display zoom)";
case "Apple A11 GPU":
return "iPhone 8 Plus (display zoom)";
}
}
}
// iPhone 5, iPhone 5C, iPhone 5S, iPhone SE
// or in zoom mode: iPhone 5, iPhone 5C, iPhone 5S, iPhone SE, iPhone 6, iPhone 6S, iPhone 7 or iPhone 8
else if (window.screen.height / window.screen.width == 1.775) {
switch (renderer) {
default:
return "iPhone 5, 5C, 5S, SE or 6, 6s, 7 and 8 (display zoom)";
case "PowerVR SGX 543":
return "iPhone 5 or 5c";
case "Apple A7 GPU":
return "iPhone 5s";
case "Apple A8 GPU":
return "iPhone 6 (display zoom)"
case "Apple A9 GPU":
return "iPhone SE or 6s (display zoom)";
case "Apple A10 GPU":
return "iPhone 7 (display zoom)";
case "Apple A11 GPU":
return "iPhone 8 (display zoom)";
}
}
// iPhone 4 or 4s
else if ((window.screen.height / window.screen.width == 1.5) && (ratio == 2)) {
switch (renderer) {
default:
return "iPhone 4 or 4s";
case "PowerVR SGX 535":
return "iPhone 4";
case "PowerVR SGX 543":
return "iPhone 4s";
}
}
// iPhone 1, 3G or 3GS
else if ((window.screen.height / window.screen.width == 1.5) && (ratio == 1)) {
switch (renderer) {
default:
return "iPhone 1, 3G or 3GS";
case "ALP0298C05":
return "iPhone 3GS";
case "S5L8900":
return "iPhone 1, 3G";
}
// Not an iPhone.
} else {
return "Not an iPhone";
}
}
And here's the JavaScript code snippet for iPads:
// iPad model checks.
function getiPadModel(){
// Create a canvas element which can be used to retreive information about the GPU.
var canvas = document.createElement("canvas");
if (canvas) {
var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (context) {
var info = context.getExtension("WEBGL_debug_renderer_info");
if (info) {
var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
}
}
}
if(window.screen.height / window.screen.width == 1024 / 768) {
// iPad, iPad 2, iPad Mini
if (window.devicePixelRatio == 1) {
switch(renderer) {
default:
return "iPad, iPad 2, iPad Mini";
case "PowerVR SGX 535":
return "iPad"
case "PowerVR SGX 543":
return "iPad 2 or Mini";
}
// iPad 3, 4, 5, 6, Mini 2, Mini 3, Mini 4, Air, Air 2
} else {
switch(renderer) {
default:
return "iPad 3, 4, 5, 6, Mini 2, Mini 3, Mini 4, Air, Air 2";
case "PowerVR SGX 543":
return "iPad 3";
case "PowerVR SGX 554":
return "iPad 4";
case "Apple A7 GPU":
return "iPad Air, Mini 2, Mini 3";
case "Apple A8X GPU":
return "iPad Air 2";
case "Apple A8 GPU":
return "iPad Mini 4";
case "Apple A9 GPU":
return "iPad 5, Pro 9.7";
case "Apple A10 GPU":
return "iPad 6";
}
}
// iPad Pro 10.5
} else if (window.screen.height / window.screen.width == 1112 / 834) {
return "iPad Pro 10.5";
// iPad Pro 11
} else if (window.screen.height / window.screen.width == 2388 / 1668) {
return "iPad Pro 11";
// iPad Pro 12.9, Pro 12.9 (2nd Gen), Pro 12.9 (3rd Gen)
} else if (window.screen.height / window.screen.width == 1366/ 1024) {
switch(renderer) {
default:
return "iPad Pro 12.9, Pro 12.9 (2nd Gen), Pro 12.9 (3rd Gen)";
case "Apple A12X GPU"
return "iPad Pro 12.9 (3rd Gen)";
case "Apple A10X GPU":
return "iPad Pro 12.9 (2nd Gen)";
case "Apple A9 GPU":
return "iPad Pro 12.9";
}
} else {
return "Not an iPad";
}
}
All code and methods shared in our blogs are only relevant as long as Apple do not block the information that can be accessed.
Try it for yourself, or simply jump straight to evaluating our enhanced Data file by starting a free trial today. You can also see an example of the data we can obtain by using any Apple device to test your device.