프로그레시브 웹 앱의 '홈 스크린에 추가' 동작에 새로운 기능

'홈 스크린에 추가' 프롬프트가 나타나는 방식과 시점에 대한 통제권을 더 많이 가졌으면 한다는 개발자들의 의견을 자주 들었습니다. Android에서는 Chrome 68부터 이 프롬프트가 나타나는 시점에 관한 제어권을 개발자에게 더 많이 제공하는 방향으로 바뀝니다. 개발자는 이제 '홈 스크린에 추가' 동작에 대한 컨텍스트를 추가로 제공함으로써 클릭률을 높일 수 있습니다.


홈 스크린에 추가 대화상자


'홈 스크린에 추가' 기준을 충족하는 사이트의 경우 Chrome에서 beforeinstallprompt 이벤트를 발생시켜 '홈 스크린에 추가' 배너를 더 이상 자동으로 표시하지 않습니다. 대신에 해당 이벤트 발생 시 개발자가 이벤트를 저장하고 앱에 설치 가능함을 나타내는 버튼이나 다른 UI 요소를 추가할 수 있습니다. 사용자가 설치 버튼을 클릭할 때 개발자가 저장된 beforeinstallprompt 이벤트에서 prompt()를 호출하여 새로운 '홈 스크린에 추가' 모달 대화상자를 표시할 수 있습니다. beforeinstallprompt 이벤트는 사용자 동작이 없더라도 시작될 수 있지만, prompt()의 경우 사용자 동작이 필요합니다.


let installPromptEvent;

window.addEventListener('beforeinstallprompt', (event) => {
 // Prevent Chrome <= 67 from automatically showing the prompt
 event.preventDefault();
 // Stash the event so it can be triggered later.
 installPromptEvent = event;
 // Update UI notify the user they can add to home screen
 document.querySelector('#install-button').disabled = false;
});



개발자에게 beforeinstallpromptevent를 처리하고 앱에 설치 버튼을 추가할 시간을 주기 위한 임시 조치로서, 사용자가 '홈 스크린에 추가' 기준을 충족하는 사이트를 처음 방문할 때 Chrome은미니 정보 표시줄을 표시합니다. 일단 미니 정보 표시줄을 해제하고 나면 충분한 시간(현재는 3개월)이 경과해야 이 표시줄이 다시 표시됩니다.


홈 스크린에 추가 미니 정보 표시줄


이 새로운 UI 요소에 대한 자세한 내용, 코드 샘플 및 스크린샷은 홈 스크린에 추가 동작 변경 사항을 참조하세요.




Payment Handler API

Payment Request API 덕분에 완벽한 네이티브 브라우저 UI를 사용자가 기본 설정한 결제 및 배송 주소 양식과 결합하여 웹 환경에서 더욱 간단하고 빠르게 온라인으로 체크아웃할 수 있게 되었습니다.


이제 막 출시된 Payment Handler API웹 기반 결제 앱을 사용하여 Payment Request 환경 내에서 바로 간편하게 결제할 수 있도록 함으로써 Payment Request의 적용 범위를 넓혀줍니다.


const request = new PaymentRequest([{
 // Your custom payment method identifier comes here
 supportedMethods: 'https://bobpay.xyz/pay'
}], {
 total: {
   label: 'total',
   amount: { value: '10', currency: 'USD' }
 }
});


Payment Request API를 통한 결제. "Pay with BobPay"는 Payment Handler API로 빌드한 맞춤 결제 방법입니다.




사용자가 원치 않는 대상으로 이동하지 않도록 보호

이번 Chrome 버전에서 우리는 사용자 환경 개선을 위해 몇몇 사용자 인터페이스 동작을 변경하고 있습니다.




교차 출처(cross-origin) iframe에서 리디렉션하려면 사용자 동작 필요

sandbox 속성으로 금지하지 않는 한, iframe에 삽입된 콘텐츠는 일반적으로 최상위 검색 컨텍스트를 다른 웹사이트로 안내할 수 있습니다. 이 기능은 SSO(Single-Sign-On) 제공업체와 결제 처리업체를 포함한 많은 유형의 웹사이트에서 사용됩니다. 안타깝게도, 이 동작은 사용자에게 알리지 않거나 사용자 동의 없이 사용자가 원치 않는 대상으로 사용자를 리디렉션하는 수단으로 흔히 악용되기도 합니다.


Chrome 68부터는 iframe에 삽입되는 콘텐츠가 최상위 검색 컨텍스트를 다른 출처로 안내하려면 사용자 동작이 필요합니다. 팝업 차단과 마찬가지로, 이 보호 기능이 트리거되면 사용자가 리디렉션을 허용해야 계속 진행할 수 있는 옵션을 제공하는 Chrome UI가 표시됩니다.


이 동작을 설명해주는 데모가 있습니다. 이 링크 이면에 나오는 데모는 Chrome 67 및 이전 버전에서의 기존 동작을 보여줍니다. 개선된 동작은 Chrome 68에서 작동합니다.




탭 언더 네비게이션 차단

페이지에서 어떤 대상으로 연결되는 팝업이 열리는 동시에 이 오프너 페이지를 타사 콘텐츠로 안내할 때 이를 탭 언더(tab-under)라고 합니다. 이 동작은 보통 사용자를 바라는 대상으로 보내는 동시에 원치 않는 대상을 포함한 또 다른 탭을 만드는 데 사용됩니다. 팝업과 마찬가지로, Chrome에서는 이처럼 원치 않는 네비게이션을 방지하고 그 대신에 사용자가 이 리디렉션을 따라 새로운 방향으로 이동할지 선택할 수 있도록 네이티브 UI를 사용자에게 보여줍니다.




Page Lifecycle API

애플리케이션 수명 주기는 첨단 운영체제에서 리소스를 관리하는 핵심적인 방식입니다. Android, iOS 그리고 최근에는 Windows에서도 플랫폼에서 언제든 앱을 시작하고 중지할 수 있습니다. 따라서 이러한 플랫폼에서는 리소스를 능률적으로 사용하고 사용자에게 가장 이롭게 재할당할 수 있습니다.


웹에서는 지금까지 이러한 수명 주기의 개념이 적용된 적이 없었기에, 앱이 무기한으로 활성 상태로 유지될 수 있습니다. 그래서 다수의 웹 앱과 탭을 실행하다 보면 메모리, CPU, 배터리, 네트워크 같은 중요한 리소스가 초과 구독될 수 있고 이럴 경우 최종 사용자 환경이 나빠지게 됩니다.


Chrome 68에서는 개발자가 새로운 freeze 및 resume 이벤트를 사용하여 백그라운드에서 실행 중인 탭에 대해 시스템이 시작하는 CPU 일시 중단을 수신하고 이에 대응할 수 있습니다. 메모리 보존을 위해 고정된 페이지를 삭제할 필요가 있는 경우, 이제는 document.wasDiscarded 속성을 사용할 수 있으므로 개발자는 사용자가 탭을 다시 포커스하고 페이지를 새로 고칠 때 (freeze 이벤트에 저장된) 뷰 상태를 복원할 수 있습니다. 자체 애플리케이션에서 이런 이벤트를 테스트하려는 개발자는 chrome://discards를 방문하여 페이지 고정, 다시 시작 및 삭제를 시뮬레이션할 수 있습니다.


Page Lifecycle API에 대한 자세한 내용은 사양 또는 GitHub의 설명자를 참조하세요.




이번 릴리스에 포함된 기타 기능

CSS

오버플로 약칭에서 두 개의 값 허용

overflow 약칭은 두 개의 값을 허용하여 수평 및 수직 오버플로를 서로 다른 값으로 설정할 수 있게 합니다. 두 개의 값이 지정되어 있는 경우 첫 번째 값은 overflow-x이고 두 번째 값은 overflow-y입니다. 개발자는 약칭을 변경하여 이전에는 두 개의 명령문이 필요했던 경우에 한 개의 명령문만 지정할 수 있습니다.

세 부분을 포함하는 CSS 위치 값

object-position 및 perspective-origin 속성은 "top right 20%"처럼 세 부분을 포함한 값을 더 이상 허용하지 않습니다. 이는 기본적인 형태와 그라데이션에서 위치에도 적용됩니다. 이제 유효한 위치 값은 항상 1개, 2개 또는 4개의 부분을 가질 것입니다. 3개의 부분으로 이루어진 값은 Chrome 66에서 지원이 중단되었습니다.

해상도 단위로 'x' 지원

CSS 값 및 단위 모듈 레벨 4에서 고해상도 디스플레이 지원을 위해 '픽셀당 도트 수(dot per pixel)'라는 새로운 해상도 단위를 정의합니다. 이러한 변화로 인해 기존 약어 'dppx'에 대한 동의어로서 'x'가 추가됩니다.

커서 속성에 대한 CSS 'grab' 및 'grabbing' 값의 접두사 제거

CSS 값 'grab'과 'grabbing'은 뭔가를 쥘 수 있거나 현재 쥐고 있음을 나타내는 데 흔히 사용되는 편 손 또는 쥔 손 모양으로 마우스 커서를 변경합니다. 이러한 속성의 접두사가 추가된 버전은 Chrome 1 이후로 계속 지원되었습니다. 이번 버전부터는 이러한 값에서 접두사를 제거한 버전을 Chrome에서 기본으로 지원합니다.


게임패드

게임패드용 고해상도 타임스탬프

Gamepad.timestamp는 이제 마이크로초 단위의 해상도를 가진 고해상도 단조 시간인 DOMHighResTimeStamp를 사용합니다. 타임스탬프는 PerformanceTiming.navigationStart 속성에서 오프셋으로 측정됩니다.


맞춤 요소

새로운 customElements.upgrade()

이 함수는 생성자가 아직 명시적으로 호출되지 않은 맞춤 요소를 위한 맞춤 요소 생성자를 호출합니다. 맞춤 요소가 innerHTML setter를 이용해 생성되고 그 상위 노드가 문서에 연결되지 않은 경우에는 연결될 때까지 맞춤 요소 생성자가 호출되지 않습니다. 이 메서드는 연결 여부에 상관없이 맞춤 요소 생성자 호출의 타이밍을 개발자가 완벽하게 제어할 수 있도록 명시적으로 허용합니다.


입력

키보드 잠금

전체 화면에서 이 API를 통해 앱이 일반적으로 Cmd-Tab/Alt-Tab 또는 Esc와 같이 시스템이나 브라우저에서 처리하는 키를 받을 수 있습니다. 사용자는 Esc 키를 2초간 눌러 키보드 잠금과 전체 화면에서 빠져나갈 수 있습니다.

PointerEvent.fromElement 및 PointerEvent.toElement를 null로 만들기

다른 브라우저와의 일관성을 향상하기 위해 fromElement 및 toElement 필드를 위한 PointerEvents는 항상 null을 보고함으로써 Pointer Events Level 2 사양을 따르지 않습니다.
(PointerEvent가 이들 필드를 상속하는) MouseEvent에서는 fromElement와 toElement가 기본 필드가 아니므로 오랫동안 주요 브라우저 간에 일관성이 없었습니다. 게다가 target과 relatedTarget이라는 일관된 대체 필드가 이미 기본으로 제공됩니다.

통합 터치 조정

터치 조정은 TouchEvent와 그에 상응하는 PointerEvent 대상을 터치 영역 내에서 최상의 대상으로 변경합니다. TouchEvent 좌표는 바뀌지 않습니다.

길게 누르는 동작을 사용자 동작으로 처리

길게 누르는 동작은 사용자와 페이지 간의 상호 작용을 나타내므로 이제는 사용자 동작으로 간주됩니다. 이에 따라 웹 앱은 길게 누르는 동작이 이루어질 때 navigator.vibrate()처럼 제한된 API를 호출하여 네이티브 동작에 일치시킬 수 있습니다.


미디어

WebAudio: AudioParams에 대해 사용자가 선택할 수 있는 자동화 비율 추가

속성을 사용하여 AudioParam이 'a-rate'인지 'k-rate'인지 선택할 수 있습니다. 전부는 아니지만 대부분의 AudioParam 속성을 통해 사양에 주어진 것처럼 비율을 변경할 수 있습니다.
예를 들어 기본 'a-rate' 자동화를 사용하는 BiquadFilterNode는 매개변수와 필터 계수 사이의 관계가 복잡하므로 계산 비용이 많이 듭니다. 이처럼 빠른 자동화가 필요하지 않을 경우(대부분의 일반적인 경우가 이에 해당), 매개변수를 'k-rate'로 설정할 수 있습니다.


ServiceWorker

서비스 워커 스크립트를 위한 캐시 관리 개선

서비스 워커에 대한 업데이트 요청 시 HTTP 캐시는 무시됩니다. importScripts 요청은 계속 HTTP 캐시를 거칩니다. 하지만 이는 단지 기본 설정일 뿐입니다. 이 동작을 제어할 수 있는 ServiceWorkerRegistration.updateViaCache라는 새로운 등록 옵션을 사용할 수 있습니다.
이전에는 서비스 워커에 대한 업데이트가 있는지 확인하는 HTTP 요청을 기본적으로 HTTP 캐시가 수행했습니다. 서비스 워커에서 Cache-Control 헤더를 무심코 설정한 경우에는 서비스 워커 업데이트를 지연할 수 있었으며, 서비스 워커에 사이트의 다른 자산에 대한 버전 관리 정보가 포함된 경우 해당 업데이트 역시 지연되었습니다.


WebRTC

RTCRtpSender.getParameters()/setParameters()가 트랙 인코딩 반환 및 제어

getParameters()setParameters() 메서드는 RTCRtpSender.track 속성이 인코딩되어 원격 RTCRtpReceiver로 전송되는 방식에 대한 RTCRtpSender 객체의 현재 매개변수를 반환하거나 업데이트합니다. 이러한 메서드를 사용하면 SDP 개조 또는 재협상을 전혀 수행하지 않고도 최대 전송 비트 전송률과 같은 WebRTC 스트림의 인코딩 매개변수를 변경할 수 있습니다.




지원 중단 및 상호 운용성 개선 사항

Chrome에서는 가끔 다른 브라우저와의 상호 운용성 증대를 위해 지원 중단, 삭제 또는 변경되는 기능이 있습니다. 이번 Chrome 버전에도 다음과 같이 변경되는 사항이 있습니다.

필터에서 음의 밝기 값 지원 중단 및 삭제

사양을 준수하기 위해 필터의 brightness() 함수는 더 이상 음수 값을 허용하지 않습니다.

document.createTouch 삭제

Chrome 48 이후로 Touch() 생성자가 지원되었으므로 document.createTouch() 메서드가 삭제됩니다.

Document.selectedStylesheetSet 및 Document.preferredStylesheetSet 삭제

Document.selectedStylesheetSet 및 Document.preferredStylesheetSet 속성은 Chrome과 WebKit에서만 구현되고 기본 속성이 아니므로 삭제됩니다. 이들 속성의 기본 버전은 2016년에 사양에서 삭제되었습니다.

WEBGL_compressed_texture_atc


이전에는 Chrome에서 AMD_compressed_ATC_texture 형식을 제공했습니다. 하드웨어 지원이 거의 제로화되는 수준으로 줄었으므로 WebGL Working Group에서 확장을 거부했습니다. 이에 따라 해당 지원 기능이 삭제되었습니다.






Polarsteps의 모험가 Niek Bokkers(네덜란드), Quiltuduko의 아티스트 Faith Ringgold(미국), Be My Eyes의 의자 복원 전문가 Hans Jorgen Wiberg(덴마크)의 이야기 영상을 보세요. g.co/play/imakeapps에서 이 세 사람과 그들이 사용하는 앱에 관한 자세한 내용을 읽어보실 수도 있습니다.


여러분의 이야기를 공유하세요


여러분의 소중한 경험도 듣고 싶습니다. 사용하시는 소셜 채널에서 해시태그 #IMakeApps를 사용해 자신이 작업하는 앱이나 게임, 제작 과정에서 맡으신 역할, 일터를 벗어났을 때 자연인으로서의 자신을 가장 잘 묘사해주는 이미지 등 다양한 이야기를 공유해 주세요. 정기적으로 소셜 채널을 통해 꼭 들려드리고 싶은 이야기를 모아 공유하겠습니다.


앞으로 공개할 #IMakeApps 영상물에 주인공이 되어보세요. 공유해주시고 싶은 이야기가 있으시면 자신에 대한 이야기와 함께 제작 과정에 참여한 앱이나 게임에 대해 자세히 들려주시기 바랍니다. 출연 희망자께서는 자기 추천 양식에 필요한 내용을 채워주세요.


Twitter, YouTube, LinkedIn에서 팔로우하여 #IMakeApps 스토리를 계속 관심 있게 지켜봐 주세요.

이 블로그 게시물이 얼마나 유용했는지 알려주세요.

play_logo_16_9.png


지난 겨울 블로그 포스트 (원문, 한국어)를 통해 알려드린 대로, 2018년 8월부터 Google Play Store에 제출되는 모든 새로운 앱과 게임은 대상 SDK API 레벨(Target SDK Level)이 26 이상(Android 8.0 Oreo)이어야 합니다. 또한 2018년 11월부터는 기존 앱과 게임을 업데이트할 때도 동일한 정책이 적용됩니다. 또한, 2019년 8월 부터는 네이티브 라이브러리를 포함한 새 앱과 앱 업데이트에서 32비트 버전 외에 64비트 버전도 함께 제공되어야 합니다. 이는 보안 및 성능에 최적화된 최신 API를 기반으로 앱이 만들어지고, 사용자가 그 혜택을 온전히 누릴 수 있도록 보장하기 위한 것입니다.




다음은 여러분이 알아야 하는 몇 가지 중요한 변경사항입니다.
  • 대상 API 23 이상으로 빌드된 앱은 반드시 런타임 권한 모델을 사용해야합니다.
  • 대상 API 24 이상으로 빌드된 앱은 정식 NDK에 포함되지 않은 라이브러리에 동적으로 링크할 수 없습니다. 비공식 라이브러리를 명시적으로 사용하고 있지 않더라도, 참조하고 있는 다른 라이브러리에서 비공식 라이브러리를 링크해 사용하고 있을 수 있습니다. 따라서 대상 API 레벨을 24 미만에서 26이상으로 변경한 후에는 꼭 Android 7.0 이 후 버전에서 동작하는 기기에서 앱 동작을 테스트 해야합니다. 네이티브 코드를 사용하는 앱의 경우 공개된 NDK API만 사용해야 합니다.
  • 푸시 알림을 사용하는 경우 Google 클라우드 메시징(메시지 수신용) 또는 Firebase 클라우드 메시징 중 하나를 사용할 것입니다. 이 때, API 레벨 26을 지원하기 위해서는 반드시 Google Play Service SDK 10.2.1 혹은 그 이상 버전 SDK (2017년 3월 21일 출시)를 사용해야합니다.
  • OBB - OBB 파일에 액세스하기 전에 해당 디렉토리에 액세스가 가능한지 확인이 필요합니다. 일부 단말에서는 기기상의 문제로 인해 외부 저장소 액세스 권한이 자동으로 부여되지 않습니다. 이런 경우에는 API를 사용하여 액세스 권한을 명시적으로 요청해야 하며, 이 권한이 부여되지 않은 경우는 매끄럽게 처리해야 합니다. 또한 외부 저장소 액세스를 위한 항목을 매니페스트에 추가하세요: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />




이 작업을 왜 수행하나요?
Android의 모든 새로운 버전에는 Android 사용자를 위한 새로운 개선 사항과 혜택이 있습니다. 그 중 앱과 게임이 최신 SDK를 대상으로 해야만 개선의 효과가 나타나는 항목들이 있습니다. 민감한 사용자 데이터(예: 연락처 또는 위치)에 대한 더 나은 제어, 개선된 배터리 수명, 메모리 사용량 감소, 엄격한 백그라운드 실행 제한 등이 있습니다.


API 26을 대상으로 하려면 언제 앱을 업데이트해야 하나요?
최대한 빨리 하는 것이 좋습니다. Android 8.0 Oreo SDK(API 레벨 26)를 설치해 보고 게임에 비호환성/문제가 없는지 확인해야 합니다.


Android 8.0을 대상으로 업데이트하려면 얼마나 많은 작업이 필요한가요?
몇 가지 요인에 따라 달라질 수 있습니다. 게임 업데이트를 정기적으로 출시하고 최신 Android SDK를 대상으로 하는 데 적극적인 분이라면 이미 API 26을 대상으로 할 가능성이 있으며 아니면 API 25를 API 26으로 마이그레이션하면 됩니다.


그러나 게임이 오래되고 API 26과 호환되지 않는 타사 SDK가 이 게임에 사용되는 경우에는, 이러한 외부 종속성을 업데이트하여 이러한 변경사항에 대비해야 합니다.


호환되지 않는 특정 광고 네트워크나 SDK를 사용 중인 경우에는 어떻게 해야 하나요?
먼저, 호환되지 않는 부분이 무엇인지 저희 (주> 채널을 활용해주세요) 에게 알려주세요.


둘째, 이 광고 네트워크나 SDK 개발업체의 담당자에게 연락하여 이번 변경사항과 관련하여 우려 사항이 있다고 알려주세요. 우리는 모든 사용자들의 이익을 위해 전체 Android 생태계가 이 변경사항을 수용하기를 희망합니다.


단순한 매니페스트 파일 변경사항인가요?
매니페스트 변경사항은 시작에 불과합니다. 현재 API 버전에 따라 다음과 같은 동작 변경 사항이 있을 수 있습니다. 개발자 사이트의 다음 내용을 참조하세요.


64비트 지원을 추가하라는 것은 무슨 뜻인가요?
앱이 64비트 환경에서 실행될 수 있습니다. 따라서 32비트 전용 라이브러리가 있는 분은 64비트 라이브러리도 함께 포함시키세요. 이것은 2019년 8월에 적용될 예정입니다.


내 앱이 매년마다 최신 API를 대상으로 해야 하나요?
모든 주요 Android 출시 후에는 앱이 “최근 Android API 레벨”을 대상으로 해야 합니다. 즉, 마지막 주요 Android 출시를 대상으로 합니다(예: P 출시의 경우 Oreo, Q 출시의 경우 P 등).


저는 Unity로 게임을 빌드하는데 영향이 있을까요?
네, 영향을 받을 가능성이 큽니다. 기본적으로 Unity는 시스템에 설치된 최고 레벨 SDK로 TargetSDK를 자동 설정합니다. 따라서 (Build Settings > Android > Player Settings)에서 Unity의 Android 빌드 설정을 확인하고, 현재 선택된 대상 API 레벨을 확인하는 것이 중요합니다. 최신 SDK를 설치하려면 Android Studio를 열고, “Tools > Android > SDK Manager > Android SDK > SDK Platforms”로 이동하여 Android 8.0 Oreo가 설치되었는지 확인하세요.