OS 통합

웹 앱은 도달범위가 넓습니다. 여러 플랫폼에서 실행됩니다. 링크를 통해 쉽게 공유할 수 있습니다. 그러나 전통적으로 운영 체제와의 통합이 부족했습니다. 얼마 전까지만 해도 설치할 수 없었습니다. 다행히 지금은 이러한 작업이 변경되었으며, 이제 이러한 통합을 활용하여 PWA에 유용한 기능을 추가할 수 있습니다. 이러한 옵션 중 몇 가지를 살펴보겠습니다.

파일을 사용하는 일반적인 사용자 워크플로는 다음과 같습니다.

  • 기기에서 파일 또는 폴더를 선택하여 직접 엽니다.
  • 해당 파일 또는 폴더를 변경하고 변경사항을 직접 다시 저장합니다.
  • 새 파일 및 폴더를 만듭니다.

File System Access API 이전에는 웹 앱에서 이 작업을 수행할 수 없었습니다. 파일을 열려면 파일을 업로드해야 하고, 변경사항을 저장하려면 사용자가 파일을 다운로드해야 했으며, 웹에서는 사용자의 파일 시스템에 새 파일과 폴더를 만들 수 있는 권한이 전혀 없었습니다.

파일 열기

파일을 열려면 window.showOpenFilePicker() 메서드를 사용합니다. 이 메서드에는 버튼 클릭과 같은 사용자 동작이 필요합니다. 파일을 열기 위한 나머지 설정은 다음과 같습니다.

  1. 파일 시스템 액세스의 파일 선택 도구 API에서 파일 핸들을 캡처합니다. 이렇게 하면 파일에 대한 기본 정보가 제공됩니다.
  2. 핸들의 getFile() 메서드를 사용하면 파일에 관한 추가 읽기 전용 속성 (예: 이름, 최종 수정일)이 포함된 File라는 특별한 종류의 Blob를 얻게 됩니다. Blob이므로 Blob 메서드를 호출하여(예: text()) 콘텐츠를 가져올 수 있습니다.
// Have the user select a file.
const [ handle ] = await window.showOpenFilePicker();
// Get the File object from the handle.
const file = await handle.getFile();
// Get the file content.
// Also available, slice(), stream(), arrayBuffer()
const content = await file.text();

변경사항 저장

파일에 변경사항을 저장하려면 사용자 동작도 필요합니다. 결과:

  1. 파일 핸들을 사용하여 FileSystemWritableFileStream를 만듭니다.
  2. 스트림을 변경합니다. 이렇게 해도 기존 파일은 업데이트되지 않습니다. 대신 일반적으로 임시 파일이 생성됩니다.
  3. 마지막으로 변경을 완료했으면 스트림을 닫습니다. 그러면 변경사항이 '임시'에서 '영구'로 바뀝니다.

코드에서 이를 확인해 보겠습니다.

// Make a writable stream from the handle.
const writable = await handle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();

파일 처리

File System Access API를 사용하면 앱 내에서 파일을 열 수 있습니다. 하지만 그 반대의 경우에는 어떻게 해야 할까요? 사용자는 자주 사용하는 앱을 파일 열기에 사용하는 기본 앱으로 설정하고 싶어 합니다. 파일 처리 API는 설치된 PWA를 사용할 수 있도록 하는 실험용 API입니다. 사용자 기기에서 파일 핸들러로 등록하고 PWA가 웹 앱 매니페스트에서 지원하는 MIME 유형 및 파일 확장자를 지정합니다. 지원되는 확장 프로그램에 맞춤 파일 아이콘을 지정할 수 있습니다.

등록이 완료되면 설치된 PWA가 사용자의 파일 시스템에서 옵션으로 표시되어 사용자가 파일을 직접 열 수 있습니다. 다음은 텍스트 파일을 읽기 위한 PWA의 매니페스트 설정 예시입니다.

...
"file_handlers": [
     {
         "action": "/open-file",
         "accept": {
             "text/*": [".txt"]
         }
     }
]
...

URL 처리

URL 처리를 사용하면 PWA가 운영체제에서 범위에 속하는 링크를 캡처하여 기본 브라우저 탭이 아닌 PWA 창 내에서 렌더링할 수 있습니다. 예를 들어 PWA로 연결되는 메시지를 수신하거나 PWA에서 딥 링크 (특정 콘텐츠를 가리키는 URL)를 클릭하면 콘텐츠가 독립형 창에서 열립니다.

이 동작은 사용자가 Chrome으로 PWA를 설치하는 경우와 같이 WebAPK가 사용될 때 Android에서 자동으로 사용 가능합니다. Safari에서 iOS 및 iPadOS에 설치된 PWA의 URL을 캡처할 수 없습니다.

데스크톱 브라우저의 경우 웹브라우저 커뮤니티에서 새로운 사양을 만들었습니다. 이 사양은 현재 실험용입니다. 새 매니페스트 파일 멤버 url_handlers를 추가합니다. 이 속성에는 PWA에서 캡처하려는 출처 배열이 필요합니다. PWA의 출처는 자동으로 부여되며, 다른 출처는 web-app-origin-association라는 파일을 통한 작동 처리를 허용해야 합니다. 예를 들어 PWA의 매니페스트가 web.dev에서 호스팅되고 app.web.dev 출처를 추가하려는 경우 다음과 같습니다.

"url_handlers": [
    {"origin": "https://app.web.dev"},
]

이 경우 브라우저는 파일이 app.web.dev/.well-known/web-app-origin-association에 있는지 확인하여 PWA 범위 URL의 URL 처리를 수락합니다. 개발자가 이 파일을 만들어야 합니다. 다음 예에서 파일은 다음과 같습니다.

{
    "web_apps": [
        {
            "manifest": "/mypwa/app.webmanifest",
            "details": {
                "paths": [ "/*" ]
            }
        }
    ]
}
드림

URL 프로토콜 처리

URL 처리는 표준 https 프로토콜 URL에서 작동하지만 pwa://와 같은 맞춤 URI 스키마를 사용할 수도 있습니다. 여러 운영체제에서 설치된 앱은 앱이 스키마를 등록하여 이 기능을 얻습니다.

PWA의 경우 이 기능은 데스크톱 기기에서만 사용할 수 있는 URL 프로토콜 핸들러 API를 사용하여 사용 설정됩니다. PWA를 앱 스토어에 배포해야만 휴대기기에 맞춤 프로토콜을 허용할 수 있습니다.

등록하려면 registerProtocolHandler() 메서드를 사용하거나 매니페스트에서 protocol_handlers 멤버를 PWA 컨텍스트에서 로드하려는 URL 및 원하는 스키마와 함께 사용합니다. 예를 들면 다음과 같습니다.

...
{
  "protocol_handlers": [
    {
      "protocol": "web+pwa",
      "url": "/from-protocol?value=%s"
    },
  ]
}
...

from-protocol URL을 올바른 핸들러로 라우팅하고 PWA에서 쿼리 문자열 value를 가져올 수 있습니다. %s는 작업을 트리거한 이스케이프 URL의 자리표시자이므로 <a href="web+pwa://testing">와 같은 링크가 있는 경우 PWA에서 /from-protocol?value=testing가 열립니다.

다른 앱에 전화 걸기

URI 스키마를 사용하여 사용자의 모든 플랫폼에서 사용할 수 있습니다. 링크를 만들거나 navigator.href를 사용하고 원하는 URI 스키마를 가리키고 URL 이스케이프 형식으로 인수를 전달하기만 하면 됩니다.

전화 통화에는 tel:, 이메일 전송에는 mailto:, 문자 메시지 전송에는 sms:와 같이 잘 알려진 표준 스키마를 사용할 수 있습니다. 또는 다른 앱의 URL 스키마(예: 잘 알려진 메시지, 지도, 탐색, 온라인 회의, 소셜 네트워크, 앱 스토어)

웹 공유

브라우저 지원

  • Chrome: 89. <ph type="x-smartling-placeholder">
  • Edge: 93. <ph type="x-smartling-placeholder">
  • Firefox: 깃발 뒤쪽에 있습니다.
  • Safari 12.1. <ph type="x-smartling-placeholder">

소스

Web Share API를 사용하면 PWA에서 공유 채널을 통해 기기에 설치된 다른 앱으로 콘텐츠를 전송할 수 있습니다.

이 API는 Android, iOS, iPadOS, Windows, ChromeOS 등 share 메커니즘이 있는 운영체제에서만 사용할 수 있습니다. 다음을 포함하는 객체를 공유할 수 있습니다.

  • 텍스트 (titletext 속성)
  • URL (url 속성)
  • 파일 (files 속성)

현재 기기에서 텍스트와 같은 간단한 데이터의 경우 공유할 수 있는지 확인하려면 navigator.share() 메서드가 있는지 확인하여 navigator.canShare() 메서드가 있는지 확인하는 파일을 공유합니다.

navigator.share(objectToShare)를 호출하여 공유 작업을 요청합니다. 이 호출은 undefined로 확인되거나 예외와 함께 거부되는 프로미스를 반환합니다.

웹 공유 덕분에 공유 시트가 열리는 Android 및 iOS용 Safari의 Chrome

웹 공유 대상

Web Share Target API를 사용하면 PWA가 PWA인지 여부와 관계없이 해당 기기에 있는 다른 앱의 공유 작업의 타겟이 될 수 있습니다. PWA는 다른 앱에서 공유한 데이터를 수신합니다.

현재 WebAPK 및 ChromeOS가 포함된 Android에서 사용할 수 있으며 사용자가 PWA를 설치한 후에만 작동합니다. 앱이 설치되면 브라우저가 운영 체제 내에 공유 타겟을 등록합니다.

웹 공유 타겟 초안 사양에 정의된 share_target 멤버를 사용하여 매니페스트에 웹 공유 대상을 설정합니다. share_target는 일부 속성이 있는 객체로 설정됩니다.

action
공유 데이터를 수신할 것으로 예상되는 PWA 창에 로드될 URL
method
이 작업에 사용되는 HTTP 동사 메서드(예: GET, POST, PUT)입니다.
enctype
(선택사항) 매개변수의 인코딩 유형입니다. 기본값은 application/x-www-form-urlencoded이지만 POST과 같은 메서드의 경우 multipart/form-data로 설정할 수도 있습니다.
params
선택한 인코딩을 사용하여 브라우저에서 URL (method: 'GET'의 경우) 또는 요청 본문에 전달할 인수 (웹 공유의 키: title, text, url, files)에 공유 데이터를 매핑하는 객체입니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.

예를 들어 다음과 같이 매니페스트에 추가하여 공유 데이터 (제목 및 URL만 해당)를 수신하도록 PWA에 정의할 수 있습니다.

...
"share_target": {
   "action": "/receive-share/",
   "method": "GET",
   "params": {
      "title": "shared_title",
      "url": "shared_url"
   }
}
...

이전 샘플에서 시스템의 앱이 제목이 있는 URL을 공유하고 사용자가 대화상자에서 PWA를 선택하면 브라우저는 원본의 /receive-share/?shared_title=AAA&shared_url=BBB로 이동하는 새로운 탐색을 생성합니다. 여기서 AAA는 공유 제목이고 BBB는 공유 URL입니다. JavaScript를 사용하여 URL 생성자로 파싱하여 window.location 문자열에서 이 데이터를 읽을 수 있습니다.

브라우저가 매니페스트의 PWA 이름과 아이콘을 사용하여 운영체제의 공유 항목을 제공합니다. 해당 목적을 위해 다른 세트를 선택할 수 없습니다.

자세한 예시 및 파일 수신 방법은 Web Share Target API로 공유 데이터 받기를 참고하세요.

연락처 선택도구

브라우저 지원

  • Chrome: 지원되지 않음 <ph type="x-smartling-placeholder">
  • Edge: 지원되지 않음 <ph type="x-smartling-placeholder">
  • Firefox: 지원되지 않음 <ph type="x-smartling-placeholder">
  • Safari: 지원되지 않음 <ph type="x-smartling-placeholder">

소스

Contact Picker API를 사용하면 사용자의 모든 연락처가 포함된 기본 대화상자를 렌더링하도록 기기에 요청할 수 있으므로 사용자가 하나 이상을 선택할 수 있습니다. 그러면 PWA가 해당 연락처로부터 원하는 데이터를 수신할 수 있습니다.

Contact Picker API는 주로 휴대기기에서 사용할 수 있으며 모든 작업은 호환되는 플랫폼에서 navigator.contacts 인터페이스를 통해 처리됩니다.

navigator.contacts.getProperties()로 쿼리할 수 있는 속성을 요청하고, 원하는 속성 목록으로 단일 또는 여러 연락처 선택을 요청할 수 있습니다.

샘플 속성으로는 name, email, address, tel가 있습니다. 사용자에게 연락처를 하나 이상 선택하도록 요청하는 경우 navigator.contacts.select(properties)를 호출하여 반환받고자 하는 속성의 배열을 전달할 수 있습니다.

다음 샘플은 선택도구에서 수신한 연락처를 나열합니다.

async function getContacts() {
   const properties = ['name', 'email', 'tel'];
   const options = { multiple: true };
   try {
     const contacts = await navigator.contacts.select(properties, options);
     console.log(contacts);
   } catch (ex) {
     // Handle any errors here.
   }
}

리소스