서비스 워커를 사용하여 알림 관리

Kate Jeffreys
Kate Jeffreys

이 Codelab에서는 서비스 워커를 사용하여 알림을 관리합니다. 이 안내에서는 여러분이 서비스 워커와 알림 권한 요청 및 알림 전송의 기본 사항을 설명합니다. 알림을 복습해야 하는 경우 알림 API 시작하기 Codelab을 참고하세요 서비스 워커에 대한 자세한 내용은 맷 건트의 서비스 워커 소개를 참조하세요.

샘플 앱 리믹스 및 새 탭에서 보기

삽입된 Glitch 앱에서 알림이 자동으로 차단되므로 이 페이지에서 앱을 미리 볼 수 없습니다. 대신 다음 단계를 따르세요.

  1. 수정할 리믹스를 클릭하여 프로젝트를 수정할 수 있도록 합니다.
  2. 사이트를 미리 보려면 앱 보기를 누릅니다. 그런 다음 전체 화면 전체 화면입니다.

새 Chrome 탭에서 Glitch가 열립니다.

이 Codelab을 진행하면서 이 페이지에 삽입된 Glitch의 코드를 변경하세요. 라이브 앱에서 새 탭을 새로고침하여 변경사항을 확인하세요.

샘플 앱 및 시작 코드 익히기

먼저 새 Chrome 탭에서 라이브 앱을 살펴보세요.

  1. `Control+Shift+J` (또는 Mac의 경우 `Command+Option+J`)를 눌러 DevTools를 엽니다.
  2. 콘솔 탭을 클릭합니다.

  3. Levels(레벨) 드롭다운에서 Info(정보) 옵션이 선택되어 있는지 확인합니다. 필터 상자 옆에 있습니다.

  4. 라이브 앱의 DevTools 콘솔에 다음과 같은 콘솔 메시지가 표시됩니다.

    TODO: Implement getRegistration().

    이 Codelab에서 구현할 함수 스텁의 메시지입니다.

이제 이 페이지에 삽입된 Glitch에 있는 샘플 앱의 코드를 살펴보겠습니다.

  1. 삽입된 Glitch에서 public/index.js를 확인합니다.

    • 구현할 함수에는 registerServiceWorker, getRegistration, unRegisterServiceWorker, sendNotification라는 4개의 스텁이 있습니다.

    • requestPermission 함수는 알림 전송에 대한 사용자 권한을 요청합니다. 알림 API 시작하기 Codelab을 진행했다면 여기에서 requestPermission 함수가 사용된 것을 확인할 수 있습니다. 유일한 차이점은 권한 요청을 해결한 후 사용자 인터페이스도 업데이트된다는 것입니다.

    • updateUI 함수는 앱의 모든 버튼과 메시지를 새로고침합니다.

    • initializePage 함수는 브라우저에서 서비스 워커 기능의 기능 감지를 수행하고 앱 사용자 인터페이스를 업데이트합니다.

    • 스크립트는 페이지가 로드될 때까지 대기한 다음 페이지를 초기화합니다.

  2. 삽입된 Glitch에서 public/service-worker.js를 엽니다.

    이름에서 알 수 있듯이 이 파일을 서비스 워커

    이 파일은 앱에서 아직 사용하지 않지만 서비스 워커가 활성화되면 콘솔로 메시지를 출력하는 시작 코드를 포함하고 있습니다.

    서비스 워커가 알림을 수신할 때 알림을 처리하도록 코드를 public/service-worker.js에 추가합니다.

서비스 워커 등록

이 단계에서는 Cloud Build를 실행하는 사용자가 앱 UI에서 서비스 워커 등록을 클릭할 때 이 코드는 public/service-worker.js를 서비스 워커로 등록합니다.

  1. 삽입된 Glitch 편집기에서 public/index.js을 엽니다. registerServiceWorker 함수를 다음 코드로 바꿉니다.

    // Use the Service Worker API to register a service worker.
    async function registerServiceWorker() {
      await navigator.serviceWorker.register('./service-worker.js')
      updateUI();
    }
    

    registerServiceWorkerasync function 선언을 사용하여 프로미스를 더 편리하게 처리할 수 있도록 합니다. 이를 통해 Promise의 결정된 값을 await할 수 있습니다. 예를 들어, 위의 함수는 UI를 업데이트하기 전에 서비스 워커 등록 결과를 기다립니다. 자세한 내용은 MDN의 await를 참고하세요.

  2. 사용자가 서비스 워커를 등록할 수 있으므로, 서비스 워커 등록 객체에 대한 참조를 가져올 수 있습니다. public/index.js에서 getRegistration 함수를 다음 코드로 바꿉니다.

    // Get the current service worker registration.
    function getRegistration() {
      return navigator.serviceWorker.getRegistration();
    }
    

    위의 함수는 서비스 워커 API 현재 서비스 워커 등록을 가져옵니다(있는 경우). 이렇게 하면 서비스 워커 등록에 대한 참조를 좀 더 편리하게 가져올 수 있습니다.

  • 서비스 워커 등록 기능을 완료하려면 서비스 워커 등록을 취소하는 코드를 추가하세요. unRegisterServiceWorker 함수를 다음 코드로 바꿉니다.

    // Unregister a service worker, then update the UI.
    async function unRegisterServiceWorker() {
      // Get a reference to the service worker registration.
      let registration = await getRegistration();
      // Await the outcome of the unregistration attempt
      // so that the UI update is not superceded by a
      // returning Promise.
      await registration.unregister();
      updateUI();
    }
    

라이브 앱이 표시 중인 탭에서 페이지를 새로고침합니다. 이제 등록 서비스 워커서비스 워커 등록 취소 버튼이 작동합니다.

서비스 워커에 알림 전송

이 단계에서는 사용자가 앱 UI에서 알림 보내기를 클릭할 때 실행되는 코드를 작성합니다. 이 코드는 알림을 만들고 서비스 워커가 등록되어 있는지 확인한 다음 postMessage 메서드를 사용하여 서비스 워커에 알림을 전송합니다.

삽입된 Glitch 편집기에서 public/index.js를 열고 sendNotification 함수를 다음 코드로 바꿉니다.

// Create and send a test notification to the service worker.
async function sendNotification() {
  // Use a random number as part of the notification data
  // (so you can tell the notifications apart during testing!)
  let randy = Math.floor(Math.random() * 100);
  let notification = {
    title: 'Test ' + randy,
    options: { body: 'Test body ' + randy }
  };
  // Get a reference to the service worker registration.
  let registration = await getRegistration();
  // Check that the service worker registration exists.
  if (registration) {
    // Check that a service worker controller exists before
    // trying to access the postMessage method.
    if (navigator.serviceWorker.controller) {
      navigator.serviceWorker.controller.postMessage(notification);
    } else {
      console.log('No service worker controller found. Try a soft reload.');
    }
  }
}

코드의 역할은 다음과 같습니다.

  • sendNotification는 비동기 함수이므로 await를 사용하여 서비스 워커 등록 참조를 가져올 수 있습니다.

  • 서비스 워커의 postMessage 메서드는 앱에서 서비스 워커로 데이터를 전송합니다. 자세한 내용은 postMessage에 대한 MDN 문서를 참조하세요.

  • 이 코드는 postMessage 함수에 액세스하려고 하기 전에 navigator.serviceWorker.controller 속성이 있는지 확인합니다. 활성 서비스 워커가 없거나 페이지가 강제로 새로고침 (Shift+새로고침)된 경우 navigator.serviceWorker.controllernull입니다. 자세한 내용은 MDN의 ServiceWorker 컨트롤러 문서를 참조하세요.

서비스 워커에서 알림 처리

이 단계에서는 서비스 워커에 게시된 메시지를 처리하고 사용자에게 알림을 표시하는 코드를 서비스 워커에 작성합니다.

삽입된 Glitch 편집기에서 public/service-worker.js을 엽니다. 파일 끝에 다음 코드를 추가합니다.

// Show notification when received
self.addEventListener('message', (event) => {
  let notification = event.data;
  self.registration.showNotification(
    notification.title,
    notification.options
  ).catch((error) => {
    console.log(error);
  });
});

다음은 간단한 설명입니다.

  • self는 서비스 워커 자체에 대한 참조입니다.

  • 이제 서비스 워커가 알림 표시를 처리하지만, 기본 앱 UI는 여전히 사용자로부터 알림 권한을 받아야 합니다. 권한이 부여되지 않으면 showNotification에서 반환하는 프로미스가 거부됩니다. 위 코드는 catch 블록을 사용하여 포착되지 않은 Promise 거부 오류를 방지하고 이 오류를 좀 더 적절하게 처리합니다.

문제가 발생한 경우 glitch.com/edit/#!/codelab-notifications-service-worker-completed에서 완성된 코드를 확인하세요.

이 시리즈의 다음 Codelab인 푸시 알림 서버 빌드로 이동합니다.