기기가 iOS인지 감지


408

Modernizr로 기능을 감지하는 방법과 비슷하게 브라우저가 iOS에서 실행 중인지 감지 할 수 있는지 궁금합니다 (기능 감지가 아닌 장치 감지 임에도 불구하고).

일반적으로 대신 기능 감지를 선호하지만이 질문에 따라 비디오를 처리하는 방식으로 인해 장치가 iOS인지 여부를 찾아야합니다. YouTube API는 iPad / iPhone / 비 플래시 장치에서 작동하지 않습니다.


[iOS 5 사용자 에이전트 문자열이란 무엇입니까?] [1] (중복?)을 참조하십시오. [1] : stackoverflow.com/questions/7825873/…
dejuknow

1
이 클라이언트 쪽 또는 서버 쪽 감지입니까?
Douglas Greenshields

안녕하세요 @DouglasGreenshields, 그것은 클라이언트 측입니다
SparrwHawk

1
또한 복제본이 아닌 방법을 묻습니다. 전에는 사용자 에이전트 스니핑을 사용한 적이 없습니다.
SparrwHawk

답변:


821

iOS 감지

나는 사용자 에이전트 스니핑 팬이 아니지만 다음과 같이하십시오.

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

다른 방법은 다음에 의존합니다 navigator.platform.

var iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

iOS것 중 하나 true또는false

왜 MSStream이 아닌가

Microsoft 는 IE11에 iPhone 이라는 단어를 삽입하여 userAgent어떻게 든 Gmail을 시도했습니다. 따라서 제외해야합니다. 여기여기 에 대한 자세한 정보 .

아래는 IE11의 업데이트입니다 userAgent(Windows Phone 8.1 용 Internet Explorer 업데이트).

iPhone OS와 같은 Mozilla / 5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident / 7.0; Touch; rv : 11.0; IEMobile / 11.0; NOKIA; Lumia 930) 7_0_3 Mac OS X AppleWebKit / 537 (Gecko와 같은 KHTML) 모바일 사파리 / 537


정규식을 사용하지 않고도 더 많은 장치를 쉽게 추가 할 수 있습니다.

function iOS() {

  var iDevices = [
    'iPad Simulator',
    'iPhone Simulator',
    'iPod Simulator',
    'iPad',
    'iPhone',
    'iPod'
  ];

  if (navigator.platform) {
    while (iDevices.length) {
      if (navigator.platform === iDevices.pop()){ return true; }
    }
  }

  return false;
}

iOS()것 중 하나 true또는false

주 :navigator.userAgentnavigator.platform사용자 또는 브라우저 확장에 의해 위조 할 수 있습니다.


iOS 버전 감지

iOS 버전을 감지하는 가장 일반적인 방법은 User Agent 문자열에서 파싱하는 것입니다 . 그러나 또한이 기능 감지 추론 * ;

우리는 사실을 알고 history API에 도입 된 iOS4 - matchMedia APIiOS5를 - webAudio APIiOS6의 - WebSpeech APIiOS7에 등등 ..

참고 : 다음 코드는 신뢰할 수 없으며 최신 HTML 버전에서 이러한 HTML5 기능이 더 이상 사용되지 않으면 중단됩니다. 경고를 받았습니다!

function iOSversion() {

  if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
    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';
}

2
감사합니다 Pierre-이 코드는 더 단순 해 보이지만 모든 iDevice를 모두 입력하지 않고 'iOS'만 지정할 수 있는지 궁금합니다 .... if ((navigator.userAgent.match (/ iPhone / i)) | {(navigator.userAgent.match (/ iPod / i)) || (navigator.userAgent.match (/ iPad / i))) {// 무언가를
하세요

9
두 번째 스 니펫에서 수행하는 작업은 기능 감지가 아니라 기능 유추입니다. 기능 감지는 실제로 사용할 기능을 테스트하는 반면, 수행중인 작업은 특정 버전의 OS에서 소개되어 해당 기능에서 OS 버전을 유추하는 기능을 테스트하는 것입니다. 이후 버전의 iOS에서 이러한 기능을 제거 할 수 있기 때문에 취약합니다.
Tim Down

23
이것은 수표를 작성하는 더 좋은 방법입니다.var iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
LandonSchropp

5
참고로 navigator.platform 배열은 플랫폼 문자열에 "iPad Simulator"라는 문구가 모두 포함되어 있기 때문에 iPad Simulator에서 작동하지 않습니다.
Kevin Newman

9
iOS 13부터 iPad의 사용자 에이전트가 "Mac OS"로 변경되었습니다. Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15
따라서이

38

iOS 13 이후에는 다음과 같은 iOS 장치를 감지해야합니다. iPad는 오래된 방법으로 iOS 장치로 감지되지 않기 때문입니다 (기본적으로 활성화 된 새로운 "데스크톱"옵션으로 인해).

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

데스크탑 모드가 비활성화 된 iOS <13 또는 iPhone 또는 iPad의 첫 번째 조건, 기본 구성의 iPadOS 13의 두 번째 조건은 Macintosh Intel처럼 위치하기 때문에 실제로는 멀티 터치가있는 유일한 Macintosh입니다.

실제 솔루션보다 해킹이 아니라 안정적으로 작동합니다.

PS 앞에서 언급했듯이 IE 점검을 추가해야 할 것입니다.

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

왜이 navigator.userAgent검사에 사용하지 /iPad|iPhone|iPod/.test(navigator.platform)않습니까? 그것은 보인다 navigator.platform항상 반환 아이폰 iOS 용 'MacIntel'<= 12
카리스 테오

@CharisTheo iPad가 iOS의 userAgent에 있지 않기 때문에> = 13
Kzrbill

하지만 두 번째 검사에서 이미 iPad iOS> = 13을 확인하고 있습니까? 아니면 뭔가 빠졌습니까?
카리스 테오

navigator.maxTouchPoints iOS에서는 지원되지 않으므로 확인을 수행해도 아무런 효과가 없습니다.
PaulC

@PaulC, iOS 12 이하에서는 maxTouchPoints가 정의되지 않았지만 maxTouchPoints가 iOS 13에서 지원되므로 kikiwora가 올바른 궤도에 있습니다.
Bob Arlof

14

변수 _iOSDevicetrue 또는 false 로 설정합니다.

_iOSDevice = !!navigator.platform.match(/iPhone|iPod|iPad/);

3
무엇을합니까 !! 하다?
패트릭

4
@astronought 이중 부정은 부울로 캐스팅하는 데 사용됩니다
Vitim.us

2
@astronought bang bang, 당신은 부울 : D
Qback

1
사용 /iPhone|iPod|iPad/.test(navigator.platform)당신이 피할 수!!
lionello

10

당신이 사용하는 경우 Modernizr 하는 경우 사용자 정의 테스트를 추가 할 수 있습니다.

어떤 탐지 모드를 사용하기로 결정했는지 (userAgent, navigator.vendor 또는 navigator.platform)는 중요하지 않으므로 나중에 쉽게 사용할 수 있도록 항상 마무리 할 수 ​​있습니다.

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

2
Modernizr은 자동으로 추가 된 테스트 이름을 소문자로 사용하십시오. (이 예에서 Modernizr.isiOS는 절대로 true를 반환하지 않습니다). 내 관점에서 lib의 나쁜 행동 ...
Cétia

3
아주 작은주의 사항 : 간단 return x ? true : false하게 return Boolean(x)또는 그냥return !!x
tibalt


6

간단하고 확장하기 쉬운 버전.

var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;

1
iOS 시뮬레이터에서도이 기능을 사용하려면 다음을 사용할 수 있습니다 navigator.platform.replace(' Simulator', '')..
Koraktor

그러나 작동하지 않습니다. 원인['str'].indexOf('string') == -1
tibalt

시뮬레이터가 실행되고 있지 않으면 navigator.platform은 정확히 'iPad', 'iPhone'또는 'iPod'입니다.
Kory Nunn

4

iOS 13을 실행하는 iPad가 (으)로 navigator.platform설정되어 MacIntel있으면 iPadOS 장치를 감지하는 다른 방법을 찾아야합니다.


3

나는 몇 년 전에 이것을 썼지 만 여전히 작동한다고 믿는다.

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");

    }

2

iOS 기기의 사용자 에이전트는 iPhone 또는 iPad라고 말합니다. 해당 키워드를 기준으로 필터링합니다.


4
고려해야 할 iPod Touch도 있습니다.
Douglas Greenshields

@DouglasGreenshields 맞습니다. 그중 하나를 잊었지만 사용자 에이전트에서도 ID를 전송한다고 생각합니다.
Bryan Naegele

iPad Safari의 사용자 에이전트는 더 이상 iPadOS 13의 "iPad"를 포함하지 않습니다.
Jonny

2

Modernizr 테스트를 추가 할 때 가능하면 장치 나 운영 체제가 아닌 기능에 대한 테스트를 추가해야합니다. iPhone에 필요한 모든 테스트를 10 번 수행하면 문제가 없습니다. 일부 기능은 기능을 감지 할 수 없습니다.

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

예를 들어 iPhone (iPad 아님) 비디오는 웹 페이지에서 인라인으로 재생할 수 없으며 전체 화면으로 열립니다. 그래서 '비인 페이지 동영상'테스트를 만들었습니다.

그런 다음 CSS에서 이것을 사용할 수 있습니다 ( 테스트가 실패하면 Modernizr가 태그에 클래스 .no-inpagevideo를 추가 <html>합니다)

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

이것은 iPhone에서 비디오를 숨길 것입니다 (이 경우 실제로하는 것은 onclick을 사용하여 비디오를 재생하는 대체 이미지를 표시하는 것입니다-기본 비디오 플레이어 및 재생 버튼을 표시하고 싶지는 않습니다).


iOS10 지금은 할 수 있습니다 playsinline당신이 사용할 수 있도록 'playsInline' in document.createElement('video');테스트 지금으로 github.com/Modernizr/Modernizr/issues/2077
Simon_Weaver

2

와우, 여기에 길고 까다로운 코드가 많이 있습니다. 간단하게 해주세요.

IMHO는 빠르고 저장하고 잘 작동합니다.

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

 // or, more future-proof (in theory, probably not in practice):

 iOS = /^iP(hone|[ao]d)/.test(navigator.platform);

 // or, if you prefer readability:

 iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform);
  • regexp가 플랫폼 문자열 의 ^ s tarting 위치를 먼저 확인하고 "iP"가 없으면 중지합니다 (어쨌든 끝까지 긴 UA 문자열을 검색하는 것보다 빠름).
  • UA 검사보다 안전합니다 (navigator.platform이 가짜라고 가정합니다)
  • iPhone / iPad 시뮬레이터 감지


업데이트 : 데스크탑 모드 (따라서 기본 iPadOS 13)의 iPad는 다루지 않습니다 .
내 유스 케이스에 적합합니다. 그렇지 않은 경우 저스틴과 kikiwora의 답변을 참조하십시오.


iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform);이보다 iOS = /^(iPhone|iPad|iPod)/.test(navigator.userAgent || navigator.vendor || navigator.platform); 는 내 경우에 navigator.platform의 대체 대책으로 할 것입니다.
플랫폼

navigator.platform작동하지 않았다? 당신은 정말로 iOS에 있습니까?. jeka.info/test/navigator.html로 확인하십시오 . userAgent일부 공급 업체가 어떤 이유로 든 Apple 기기를 모방하기 위해 위조하기 때문에 오탐 (false positive)을 나타냅니다. Firefox 에서는 , 또는 아무것도 vendor반환 하지 않습니다. Google Inc.Apple Computer, Inc.
jj

1

보다 기능적인 접근 방식을 사용하여 첫 번째 답변을 약간 업데이트하십시오.

    const isIOS = [
      'iPad Simulator',
      'iPhone Simulator',
      'iPod Simulator',
      'iPad',
      'iPhone',
      'iPod',
    ].indexOf(navigator.platform) !== -1;

Brave / Chrome 개발 도구 모바일 시뮬레이터에서는 작동하지 않습니다. 나는MacIntel
sdfsdf

1

여기에 이전 답변 중 어느 것도 iOS 13을 포함한 모든 iOS 버전의 모든 주요 브라우저에서 작동하지 않습니다. 다음은 모든 iOS 버전에서 Safari, Chrome 및 Firefox에서 작동하는 솔루션입니다.

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()));
})();

이 코드 스 니펫은 간결함이나 성능이 아니라 가독성을 우선으로 작성되었습니다.

설명:

  • 사용자 에이전트에 "iPod | iPhone | iPad"중 하나가 포함 된 경우 분명히 장치는 iOS입니다. 그렇지 않으면 계속하십시오 ...

  • "Macintosh"를 포함하지 않는 다른 사용자 에이전트는 Apple 디바이스가 아니므로 iOS가 될 수 없습니다. 그렇지 않으면 Apple 기기이므로 계속하십시오 ...

  • maxTouchPoints값 이상의 값을 가진 경우 1Apple 디바이스에는 터치 스크린이 있으므로 터치 스크린이있는 Mac이 없으므로 iOS가 있어야합니다 (을 언급 할 경우 kikiwora에게 추천 maxTouchPoints). 참고 maxTouchPointsundefined우리가 그 시나리오에 대해 다른 솔루션을 필요로하므로, 아이폰 OS (12)과 아래 ...

  • iOS 12 이하에는 Mac OS에는 존재하지 않는 단점이 있습니다. 문제 volumeAudio요소 의 속성을 이외의 다른 값으로 설정할 수 없다는 것 1입니다. Apple은 AudioiOS 기기 의 요소에서 볼륨 변경을 허용하지 않지만 Mac OS의 경우 볼륨 변경을 허용하기 때문 입니다. 이 단점은 iOS 기기를 Mac OS 기기와 구별하기위한 최종 폴백 방법으로 사용할 수 있습니다.


0

당신은 또한 사용할 수 있습니다 includes

  const isApple = ['iPhone', 'iPad', 'iPod'].includes(navigator.platform)

-1

필자의 경우 사용자 에이전트는 Ipad에서 사용자 에이전트가 Mac OS와 동일하기 때문에 충분하지 않았으므로 불쾌한 트릭을 수행해야했습니다.

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
}

iOS를 감지하고 모바일을 감지하지 못한다는 질문을 읽으십시오
Cybersupernova

-2

iOS 버전을 감지하려면 다음과 같은 Javascript 코드로 사용자 에이전트를 구조화해야합니다.

 var res = navigator.userAgent.match(/; CPU.*OS (\d_\d)/);
    if(res) {
        var strVer = res[res.length-1];
        strVer = strVer.replace("_", ".");
        version = strVer * 1;
    }

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.