Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Request.Browser.IsMobileDevice not working with iPadAir2 and iOS 13.0.1

I am able to detect iPadAir2 device running on iOS 11.4 using Request.Browser.IsMobileDevice and it gives me UserAgent information saying its an iPad: enter image description here

When I do same for iPadAir2 running on iOS 13.0.1 its not giving me iPad keyword anymore: enter image description here

how do I detect its an ipad and ruuning a safari browser?

I need this to detect iPad in Razor .chtml page so I can show different Menu for my website.

I found this solution from here How to detect device name in Safari on iOS 13 while it doesn't show the correct user agent?

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

How to use this variable in razor to change website menu ?

like image 863
newdeveloper Avatar asked Oct 11 '19 15:10

newdeveloper


1 Answers

Before iOS 13 (a.k.a. before Safari started to "lie" by default) we could have had a solution like this: https://stackoverflow.com/a/32947785/292502. Now that iPad Safari mimics desktop user agent by default puts the developer in a hard spot unless the user can be expected to switch that Safari behavior off (often times the user does not even know if a device is Android tablet or an iPad).

The ASP.NET or C# versions of the Detect Mobile Browsers script also operate in C# land and you'd need to access other fields of the navigator JavaScript object.

So we have to resort to move this whole detection code into one of your JavaScript files. Then you'd start off of the JavaScript or jQuery version Detect Mobile Browsers script. I transformed that into a function which just returns the boolean verdict.

You'd add the extras what others advise, but here we'd need to make a choice: regarding what is the real reason behind we'd like to detect the device's type.

  1. If we are OK that touch screen iBooks or iMacs are considered mobile, then we can resort to a simple (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) type extra approach. with the M1 Macs this criteria would not work because those are ARM based. It depends on what the navigator say about them. This would work if our main reason is related to touch screen navigation.
  2. If we rather focus on the mobile/tablet because of the form factor and not just the touch capability, then the first approach is not adequate. We'd need to have some extra test which would reveal the "lying" Safari. The downvoted https://stackoverflow.com/a/59408181/292502 shows one possibility for that. There's no way to reveal a lying Safari other then test for some custom features which busts it. The downside of this solution is that it can be brittle if the tested capability changes in the future.

My solution would be something along the line of:

function detectmobilebrowser() {
  var userAgent = navigator.userAgent || navigator.vendor || window.opera;
  if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|android|playbook|silk|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(userAgent) ||
      /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4)))
    return true;

  // Lying iOS13 iPad
  if (userAgent.match(/Macintosh/i) !== null) {
    // need to distinguish between Macbook and iPad
    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) {
          var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
          if (renderer.indexOf("Apple") !== -1)
            return true;
        }
      }
    }
  }

  return false;
}

That first part is a modified version of the jQuery Detect Mobile Browser. The modification is the "non lying" iPad support by adding the ad into |ip(hone|od|ad). Then I add the lying iPad detection. This code may need more modification and more testing! Then you could call the detectmobilebrowser() in the appropriate places and act on it. As this is moved to JavaScript land this is not Razor solution any more, but this is how you can go about this right now in my opinion.


For my own application as well you can test this code here:

  • Testing website
  • Test source code
like image 97
Csaba Toth Avatar answered Oct 07 '22 16:10

Csaba Toth