• About Us
  • Blog
  • Basket
  • Account
  • Sign In
  •  

Blog

Missing iPad tablet web traffic?

Published on Thursday, August 22, 2019

Missing iPad tablet web traffic?

Fix mobile decrease as iOS13 rolls out

Introduction

September 2019 will herald some big changes to the world of web marketing analytics. Apple will roll out iPadOS 13 across the following iPads and with it many analytics solutions will start reporting iPad web traffic as desktop, skewing carefully crafted mobile versus desktop analysis.

  • iPad Pro (12.9-inch)
  • iPad Pro (11-inch)
  • iPad Pro (10.5-inch)
  • iPad Pro (9.7-inch)
  • iPad (sixth generation)
  • iPad (fifth generation)
  • iPad Air (third generation)
  • iPad Air 2

This blog explains why this will happen and provides a simple JavaScript tweak to fix Google Analytics and other solutions.

What's happening?

Apple iPadOS 13 includes a feature with Safari to instruct the iPad to pretend to be a Mac laptop or desktop rather than an iPad. Apple appear to be mandating an identical experience across iPad and Mac despite major differences such as the presence of a cursor. keyboard or touch screen. The feature is enabled by default in the beta versions of iPadOS 13 beta 6 and there is no reason to believe Apple will reverse the decision before production deployment. As it’s buried in the Settings menu most users won’t change it.

Safari settings in iPadOS 13 defaults
Safari settings in iPadOS 13 – defaults to Request Desktop for all web sites.

The obvious consequence of iPads pretending to be Macs is that web site analytics will report the traffic as desktop and not tablet.

There will be other side effects for web sites that seek to optimize content for tablets. Apple’s own beta web site picked the wrong defaults when accessed from an iPad upgraded to the beta.

iPadOS 13 is treated as macOS device
An iPad 5 upgraded to iPadOS 13 is treated as macOS device when it returns to the beta web site.

User-Agents

iOS 12 and earlier versions of on iPad would report the following User-Agent string when accessing web sites.

Mozilla/5.0 (iPad; CPU OS 12_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Mobile/15E148 Safari/604.1

In iPadOS 13 with desktop mode enabled the User-Agent is altered to appear as a Macintosh.

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

The important “iPad” sequence of characters has been removed and replaced with “Macintosh”. Most analytics packages use the presence of the characters “iPad” to designate web traffic from the device as iPad and therefore assign the traffic to the Tablet device category.

The Fix – Intel vs Apple

There is another way of determining if the web page is displayed on an iPad or a Macintosh. Apple use Intel graphics processors within Macintosh devices. iPad’s use Apple’s own graphic processors.

The Web Graphics Language (WebGL) APIs available in JavaScript offer a feature to determine the manufacturer of the graphics renderer. The following JavaScript provides the logic needed setting the boolean flag iPad to true if the web page is displayed on a device with an Apple processor (currently only an iPad).

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example Apple Device Type</title>
    <style>
        table, input { width: 100%; }
        tr td:first-child { white-space: nowrap; }
        tr td:last-child { width: 100%; }
    </style>
</head>
<body>
    <table>
        <tr>
            <td><label for="typeField">Device Type</label></td>
            <td><input type="text" id="typeField" /></td>
        </tr>
        <tr>
            <td><label for="uaField">User-Agent</label></td>
            <td><input type="text" id="uaField" /></td>
        </tr>
    </table>
    <script>

        // Returns the portion of the User-Agent which represents the family of
        // Apple products the device belongs.
        // @return iPhone, iPad or Macintosh otherwise empty string
        function getFamily() {
            var segments = /iPhone|iPad|Macintosh/.exec(navigator.userAgent);
            if (segments && segments.length > 0) {
                return segments;
            }
        }

        // Try getting the renderer string via the conventional debug
        // extension.
        // @return the UNMASKED_RENDERER_WEBGL parameter value.
        function getReportedRenderer() {
            var canvas = document.createElement("canvas");
            if (canvas != null) {
                var context = canvas.getContext("webgl") ||
                    canvas.getContext("experimental-webgl");
                if (context) {
                    var info = context.getExtension(
                        "WEBGL_debug_renderer_info");
                    if (info) {
                        return context.getParameter(
                            info.UNMASKED_RENDERER_WEBGL);
                    }
                }
            }
        }

        // Returns the Apple device in a form that will match Google Analytics
        // device type settings.
        // @return Tablet, Mobile, Desktop or Unknown.
        function getAppleDeviceType() {
            var family = getFamily();

            // If User-Agent reports Macintosh double check this against the
            // graphics renderer.
            if (family == "Macintosh") {
                renderer = getReportedRenderer();
                if (renderer.includes("Apple")) {
                    family = "iPad";
                }
                else if (renderer.includes("Intel")) {
                    family = "Macintosh";
                }
            }

            // Map the Apple product family to the Google device type.
            switch (family) {
                case "iPad": return "Tablet";
                case "iPhone": return "Mobile";
                case "Macintosh": return "Desktop";
                default: return "Unknown";
            }
        }

        // Get the device type.
        var deviceType = getAppleDeviceType();
        document.getElementById("typeField").value = deviceType;

        // Display the User-Agent.
        document.getElementById("uaField").value = navigator.userAgent;
    </script>
</body>
</html>
Example web page to correctly identify iPads when Desktop Mode is enabled.
 

The getReportedRenderer function in the example will return “Intel Iris OpenGL Engine” on a real Macintosh. On an iPad it’ll return “Apple GPU”. The difference in GPU manufacturer can be used to override the User-Agent.

Google Analytics

Adding the previous snippet to Google Analytics via custom dimensions is simple. Google provide a quick tutorial on custom dimensions here.

The following modified code snippet shows how to set the device type in custom dimension 1.

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example Apple Device Type</title>
    <script src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXXX-Y">
    </script>
    <script>
        window.dataLayer = window.dataLayer || [];
        function gtag() { dataLayer.push(arguments); }
        gtag('js', new Date());

        // Create a custom_map for the dimensions. Dimension 1 is
        // device type. The value is set at the end of the page.
        gtag('config', 'UA-XXXXXXXXX-Y', {
            'custom_map': {
                'dimension1': 'devicetype',
            }
        });
    </script>
    <style>
        table, input { width: 100%; }
        tr td:first-child { white-space: nowrap; }
        tr td:last-child { width: 100%; }
    </style>
</head>
<body>
    <table>
        <tr>
            <td><label for="typeField">Device Type</label></td>
            <td><input type="text" id="typeField" /></td>
        </tr>
        <tr>
            <td><label for="uaField">User-Agent</label></td>
            <td><input type="text" id="uaField" /></td>
        </tr>
    </table>
    <script>

        // Returns the portion of the User-Agent which represents the family of
        // Apple products the device belongs.
        // @return iPhone, iPad or Macintosh otherwise empty string
        function getFamily() {
            var segments = /iPhone|iPad|Macintosh/.exec(navigator.userAgent);
            if (segments && segments.length > 0) {
                return segments;
            }
        }

        // Try getting the renderer string via the conventional debug
        // extension.
        // @return the UNMASKED_RENDERER_WEBGL parameter value.
        function getReportedRenderer() {
            var canvas = document.createElement("canvas");
            if (canvas != null) {
                var context = canvas.getContext("webgl") ||
                    canvas.getContext("experimental-webgl");
                if (context) {
                    var info = context.getExtension(
                        "WEBGL_debug_renderer_info");
                    if (info) {
                        return context.getParameter(
                            info.UNMASKED_RENDERER_WEBGL);
                    }
                }
            }
        }

        // Returns the Apple device in a form that will match Google Analytics
        // device type settings.
        // @return Tablet, Mobile, Desktop or Unknown.
        function getAppleDeviceType() {
            var family = getFamily();

            // If User-Agent reports Macintosh double check this against the
            // graphics renderer.
            if (family == "Macintosh") {
                renderer = getReportedRenderer();
                if (renderer.includes("Apple")) {
                    family = "iPad";
                }
                else if (renderer.includes("Intel")) {
                    family = "Macintosh";
                }
            }

            // Map the Apple product family to the Google device type.
            switch (family) {
                case "iPad": return "Tablet";
                case "iPhone": return "Mobile";
                case "Macintosh": return "Desktop";
                default: return "Unknown";
            }
        }

        // Get the device type.
        var deviceType = getAppleDeviceType();
        document.getElementById("typeField").value = deviceType;

        // Display the User-Agent.
        document.getElementById("uaField").value = navigator.userAgent;

        // Add the device type as a custom dimension to GA.
        gtag('event', 'apple', {
            'devicetype': deviceType,
        });
    </script>
</body>
</html>
Example code snippet showing how to add device type for Apple devices into Google Analytics

Summary

We’ve solved the problem. At least until Apple iOS 14 changes things again!

51Degrees takes care of this sort of complexity, not just for Apple but all device and browser vendors. Far more information is available for 51Degrees to support use cases as varied as artificial intelligence, performance marketing and insights with data including device price, age, physical screen size, networks, chipsets, video and more.

Adding 51Degrees to analytics, eCommerce, DXP, CMS and other web platforms provides a future proof and low maintenance fix to keep up to date with changes on the web.

To understand more about how 51Degrees can help your business, speak to one of our sales team today.

Contact Us
 

It's possible Apple may decide to reverse the default setting before iPadOS 13 ships in the coming weeks. Is anyone taking bets?


51Degrees is the world's fastest and most accurate device detection solution for your website today, tomorrow and in the future. If you'd like to find out more please contact us and we'll be happy to discuss how we can help you maximize your business potential.

51Degrees enables you to detect over 55,000 different device models; allowing you to optimize your website and increase revenue.

Try 51Degrees today to add detailed device information to your website

Get Started

Comments (0)
Benjamin CB
>

Benjamin CB

Other posts by Benjamin CB
Contact author

Name:
Email:
Subject:
Message:
x

Tags

.NET 4G 51Degrees 5G Acer Adform Adtech Advertising Afilias Alcatel Amazon AMP Analysis Analytics Android Apache API Apple Asian Market ASP.NET Asus Blackberry Browser C C# Centro Chrome Cloud CMS CPU CSS3 Data Data Blog Data File Daydream Design Detection Developers Device Device Data Device Detection Device Intelligence Device Models Device property DeviceAtlas Disney dmexco DotNetNuke Download ebay Ericsson Event Facebook Firefox Foundation Framework Galaxy git repositories Google Google Analytics Google Daydream GPU GSMA Guess HAProxy Hash Trie HTC HTML5 HTTP HTTP Headers Huawei Infinix Ingeniux Internet usage iOS iOS 13 ipad iPadOS iPhone iPhone 11 Java Javascript Kentico LG Liferay LTE m.dot Memory Memory leak Meta Data Microsoft Mobile Mobile Analysis Mobile Analytics Mobile Devices Mobile Marketing Mixer Motorola Mozilla MWC MWC 2017 MWC16 Native Apps NET New Release News Nexus NFC NGINX Nokia OnePlus 5 Opera Operating System Oppo Optimisation OS Patent Performance PHP Press Release Price Band programmatic Publishers Python Redirection Research Responsive Images Responsive web design RESS Review RTB RWD Safari Samsung Scala ScientiaMobile SEO Server Server-side optimisation Seznam.cz Sitecore Smart TV Smartphone Smartwatches Sony Swedish Beers Tablet Tencent Testing Tips Tutorial Umbraco Update User Agent User-Agent Valgrind Varnish Varnish Cache Video Vodafone VoLTE Web Web Apps Web content management Webtrekk White Paper Widgets WiFi Windows WURFL Xiaomi Xperia ZTE