웹 앱은 도달범위가 넓습니다. 여러 플랫폼에서 실행됩니다. 링크를 통해 쉽게 공유할 수 있습니다. 그러나 전통적으로 운영 체제와의 통합이 부족했습니다. 얼마 전까지만 해도 설치할 수 없었습니다. 다행히 지금은 이러한 작업이 변경되었으며, 이제 이러한 통합을 활용하여 PWA에 유용한 기능을 추가할 수 있습니다. 이러한 옵션 중 몇 가지를 살펴보겠습니다.
파일 시스템 작업
파일을 사용하는 일반적인 사용자 워크플로는 다음과 같습니다.
- 기기에서 파일 또는 폴더를 선택하여 직접 엽니다.
- 해당 파일 또는 폴더를 변경하고 변경사항을 직접 다시 저장합니다.
- 새 파일 및 폴더를 만듭니다.
File System Access API 이전에는 웹 앱에서 이 작업을 수행할 수 없었습니다. 파일을 열려면 파일을 업로드해야 하고, 변경사항을 저장하려면 사용자가 파일을 다운로드해야 했으며, 웹에서는 사용자의 파일 시스템에 새 파일과 폴더를 만들 수 있는 권한이 전혀 없었습니다.
파일 열기
파일을 열려면 window.showOpenFilePicker()
메서드를 사용합니다. 이 메서드에는 버튼 클릭과 같은 사용자 동작이 필요합니다. 파일을 열기 위한 나머지 설정은 다음과 같습니다.
- 파일 시스템 액세스의 파일 선택 도구 API에서 파일 핸들을 캡처합니다. 이렇게 하면 파일에 대한 기본 정보가 제공됩니다.
- 핸들의
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();
변경사항 저장
파일에 변경사항을 저장하려면 사용자 동작도 필요합니다. 결과:
- 파일 핸들을 사용하여
FileSystemWritableFileStream
를 만듭니다. - 스트림을 변경합니다. 이렇게 해도 기존 파일은 업데이트되지 않습니다. 대신 일반적으로 임시 파일이 생성됩니다.
- 마지막으로 변경을 완료했으면 스트림을 닫습니다. 그러면 변경사항이 '임시'에서 '영구'로 바뀝니다.
코드에서 이를 확인해 보겠습니다.
// 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 스키마(예: 잘 알려진 메시지, 지도, 탐색, 온라인 회의, 소셜 네트워크, 앱 스토어)
웹 공유
브라우저 지원
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Web Share API를 사용하면 PWA에서 공유 채널을 통해 기기에 설치된 다른 앱으로 콘텐츠를 전송할 수 있습니다.
이 API는 Android, iOS, iPadOS, Windows, ChromeOS 등 share
메커니즘이 있는 운영체제에서만 사용할 수 있습니다.
다음을 포함하는 객체를 공유할 수 있습니다.
- 텍스트 (
title
및text
속성) - URL (
url
속성) - 파일 (
files
속성)
현재 기기에서 텍스트와 같은 간단한 데이터의 경우 공유할 수 있는지 확인하려면 navigator.share()
메서드가 있는지 확인하여 navigator.canShare()
메서드가 있는지 확인하는 파일을 공유합니다.
navigator.share(objectToShare)
를 호출하여 공유 작업을 요청합니다. 이 호출은 undefined
로 확인되거나 예외와 함께 거부되는 프로미스를 반환합니다.
웹 공유 대상
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로 공유 데이터 받기를 참고하세요.
연락처 선택도구
브라우저 지원
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <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.
}
}