3단계: 알람 및 알림 추가

이 단계에서 학습할 내용은 다음과 같습니다.

  • 지정된 간격으로 앱의 절전 모드를 해제하여 백그라운드 작업을 실행하는 방법
  • 화면 알림을 사용하여 중요한 것에 주의를 집중시키는 방법

이 단계를 완료하는 데 걸리는 예상 시간: 20분 이 단계에서 완료할 작업을 미리 보려면 이 페이지 하단으로 이동 ↓합니다.

리마인더로 Todo 앱 개선

앱이 닫혀 있을 때도 열려 있는 할 일이 있는 경우 사용자에게 알리는 기능을 추가하여 Todo 앱을 개선합니다.

먼저 앱에서 완료되지 않은 할 일을 정기적으로 확인할 방법을 추가해야 합니다. 다음으로 Todo 앱 창이 닫혀 있어도 앱은 사용자에게 메시지를 표시해야 합니다. 이렇게 하려면 Chrome 앱에서 알람과 알림이 작동하는 방식을 이해해야 합니다.

알람 추가

chrome.alarms를 사용하여 기상 간격을 설정합니다. Chrome이 실행 중인 동안에는 설정된 간격으로 알람 리스너가 호출됩니다.

앱 권한 업데이트

manifest.json에서 "alarms" 권한을 요청합니다.

"permissions": ["storage", "alarms"],

백그라운드 스크립트 업데이트

background.js에서 onAlarm 리스너를 추가합니다. 지금은 할 일 항목이 있을 때마다 콜백 함수가 콘솔에 메시지를 기록합니다.

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', {
    id: 'main',
    bounds: { width: 620, height: 500 }
  });
});
chrome.alarms.onAlarm.addListener(function( alarm ) {
  console.log("Got an alarm!", alarm);
});

HTML 보기 업데이트

index.html에서 알람 활성화 버튼을 추가합니다.

<footer id="info">
  <button id="toggleAlarm">Activate alarm</button>
  ...
</footer>

이제 이 새 버튼의 JavaScript 이벤트 핸들러를 작성해야 합니다. 2단계에서 살펴봤듯이 가장 일반적인 CSP 위반사항 중 하나가 인라인 자바스크립트로 인한 것입니다. index.html에서 다음 줄을 추가하여 다음 단계에서 만들 새 alarms.js 파일을 가져옵니다.

  </footer>
  ...
  <script src="js/app.js"></script>
  <script src="js/alarms.js"></script>
</body>

알람 스크립트 만들기

js 폴더에 alarms.js라는 새 파일을 만듭니다.

아래 코드를 사용하여 checkAlarm(), createAlarm(), cancelAlarm(), toggleAlarm() 메서드를 추가하고 클릭 이벤트 핸들러와 함께 알람 활성화 버튼을 클릭할 때 알람을 전환할 수 있습니다.

(function () {
  'use strict';
   var alarmName = 'remindme';
   function checkAlarm(callback) {
     chrome.alarms.getAll(function(alarms) {
       var hasAlarm = alarms.some(function(a) {
         return a.name == alarmName;
       });
       var newLabel;
       if (hasAlarm) {
         newLabel = 'Cancel alarm';
       } else {
         newLabel = 'Activate alarm';
       }
       document.getElementById('toggleAlarm').innerText = newLabel;
       if (callback) callback(hasAlarm);
     })
   }
   function createAlarm() {
     chrome.alarms.create(alarmName, {
       delayInMinutes: 0.1, periodInMinutes: 0.1});
   }
   function cancelAlarm() {
     chrome.alarms.clear(alarmName);
   }
   function doToggleAlarm() {
     checkAlarm( function(hasAlarm) {
       if (hasAlarm) {
         cancelAlarm();
       } else {
         createAlarm();
       }
       checkAlarm();
     });
   }
  $$('#toggleAlarm').addEventListener('click', doToggleAlarm);
  checkAlarm();
})();

앱을 새로고침하고 잠시 시간을 내어 알람을 활성화 (및 비활성화)합니다.

백그라운드 페이지 메시지 검사

알람이 활성화될 때마다 알람이 '울릴' 때마다 콘솔에 로그 메시지가 출력됩니다.

콘솔에 알람 메시지 인쇄

다음 사항을 확인할 수 있습니다.

  • Todo 앱 창을 닫아도 알람은 계속 울립니다.
  • ChromeOS 이외의 플랫폼에서는 모든 Chrome 브라우저 인스턴스를 완전히 닫으면 알람이 실행되지 않습니다.

chrome.alarms 메서드를 사용하는 alarms.js의 몇 가지 요소를 하나씩 살펴보겠습니다.

알람 만들기

createAlarm()에서 chrome.alarms.create() API를 사용하여 알람 활성화가 전환될 때 알람을 만듭니다.

chrome.alarms.create(alarmName, {delayInMinutes: 0.1, periodInMinutes: 0.1});

첫 번째 매개변수는 알람의 고유한 이름을 식별하는 문자열입니다(예: remindme). (참고: 이름으로 취소하려면 알람 이름을 설정해야 합니다.)

두 번째 매개변수는 alarmInfo 객체입니다. 유효한 alarmInfo 속성에는 when 또는 delayInMinutesperiodInMinutes가 있습니다. 사용자 컴퓨터의 부하를 줄이기 위해 Chrome은 알람을 1분에 한 번으로 제한합니다. 여기서는 데모 목적으로만 작은 값 (1분 기준 0.1)을 사용합니다.

알람 지우기

cancelAlarm()에서 알람 취소가 전환되면 chrome.alarms.clear() API를 사용하여 알람을 취소합니다.

chrome.alarms.clear(alarmName);

첫 번째 매개변수는 chrome.alarms.create()에서 알람 이름으로 사용한 식별 문자열이어야 합니다.

두 번째 (선택사항) 매개변수는 다음 형식을 취해야 하는 콜백 함수입니다.

function(boolean wasCleared) {...};

알람 받기

checkAlarm()에서 전환 버튼의 UI 상태를 업데이트하기 위해 chrome.alarms.getAll() API를 사용하여 생성된 모든 알람의 배열을 가져옵니다.

getAll()Alarm 객체의 배열을 전달하는 콜백 함수를 허용합니다. Alarm에 무엇이 있는지 확인하려면 다음과 같이 DevTools 콘솔에서 실행 중인 알람을 검사하면 됩니다.

chrome.alarms.getAll(function(alarms) {
  console.log(alarms);
  console.log(alarms[0]);
});

그러면 아래와 같이 {name: "remindme", periodInMinutes: 0.1, scheduledTime: 1397587981166.858}와 같은 객체가 출력됩니다.

getAll()을 사용하여 실행 중인 알람을 검사합니다.

다음 섹션 준비하기

이제 일정한 간격으로 앱을 폴링하는 알람이 준비되었으므로 시각적 알림을 추가하는 기준으로 이를 사용합니다.

알림 추가

알람 알림을 사용자가 쉽게 알아차릴 수 있는 것으로 변경해 보겠습니다. chrome.notifications를 사용하여 다음과 같은 데스크톱 알림을 표시합니다.

Todo 앱 알림

사용자가 알림을 클릭하면 Todo 앱 창이 표시됩니다.

앱 권한 업데이트

manifest.json에서 "notifications" 권한을 요청합니다.

"permissions": ["storage", "alarms", "notifications"],

백그라운드 스크립트 업데이트

background.js에서는 chrome.app.window.create() 콜백을 독립형 메서드로 리팩터링하여 재사용할 수 있습니다.

chrome.app.runtime.onLaunched.addListener(function() {
function launch() {
  chrome.app.window.create('index.html', {
    id: 'main',
    bounds: { width: 620, height: 500 }
  });
}
});
chrome.app.runtime.onLaunched.addListener(launch);
...

알람 리스너 업데이트

background.js의 맨 위에 알람 리스너에 사용되는 데이터베이스 이름의 변수를 추가합니다.

var dbName = 'todos-vanillajs';

dbName 값은 js/app.js의 17행에 설정된 데이터베이스 이름과 동일합니다.

var todo = new Todo('todos-vanillajs');

알림 만들기

새 알람을 콘솔에 로깅하는 대신 chrome.storage.local.get()를 통해 저장된 데이터를 가져오도록 onAlarm 리스너를 업데이트하고 showNotification() 메서드를 호출합니다.

chrome.alarms.onAlarm.addListener(function( alarm ) {
  console.log("Got an alarm!", alarm);
  chrome.storage.local.get(dbName, showNotification);
});

다음 showNotification() 메서드를 background.js에 추가합니다.

function launch(){
  ...
}

function showNotification(storedData) {
  var openTodos = 0;
  if ( storedData[dbName].todos ) {
    storedData[dbName].todos.forEach(function(todo) {
      if ( !todo.completed ) {
        openTodos++;
      }
    });
  }
  if (openTodos>0) {
    // Now create the notification
    chrome.notifications.create('reminder', {
        type: 'basic',
        iconUrl: 'icon_128.png',
        title: 'Don\'t forget!',
        message: 'You have '+openTodos+' things to do. Wake up, dude!'
     }, function(notificationId) {});
  }
}

chrome.app.runtime.onLaunched.addListener(launch);
...

showNotification()에서 열려 있는 (완료되지 않은) 할 일 항목이 있는지 확인합니다. 열려 있는 할 일 항목이 하나 이상 있으면 chrome.notifications.create()를 통해 알림 팝업을 만듭니다.

첫 번째 매개변수는 고유하게 식별하는 알림 이름입니다. 특정 알림과의 상호작용을 지우거나 처리하려면 ID가 설정되어 있어야 합니다. ID가 기존 알림과 일치하면 create()는 새 알림을 보내기 전에 먼저 알림을 지웁니다.

두 번째 매개변수는 NotificationOptions 객체입니다. 알림 팝업을 렌더링하는 다양한 옵션이 있습니다. 여기서는 아이콘, 제목, 메시지가 있는 '기본' 알림을 사용합니다. 다른 알림 유형에는 이미지, 목록, 진행률 표시기가 있습니다. 3단계를 완료한 후 언제든지 이 섹션으로 돌아와 다른 알림 기능을 실험해 보세요.

세 번째 (선택사항) 매개변수는 다음 형식을 취해야 하는 콜백 메서드입니다.

function(string notificationId) {...};

알림 상호작용 처리

사용자가 알림을 클릭하면 Todo 앱을 엽니다. background.js 끝에 chrome.notifications.onClicked 이벤트 핸들러를 만듭니다.

chrome.notifications.onClicked.addListener(function() {
  launch();
});

이벤트 핸들러 콜백은 단순히 launch() 메서드를 호출합니다. chrome.app.window.create()는 Chrome 앱 창이 아직 없는 경우 새 창을 만들거나 창 ID가 main인 현재 열려 있는 창에 포커스를 가져옵니다.

완성된 Todo 앱을 실행합니다.

3단계를 완료했습니다. 지금 Todo 앱을 알림 기능으로 새로고침해 보세요.

다음 동작이 예상대로 작동하는지 확인합니다.

  • 완료되지 않은 할 일 항목이 없는 경우 팝업 알림이 표시되지 않습니다.
  • 앱이 닫힐 때 알림을 클릭하면 Todo 앱이 열리거나 포커스됩니다.

문제 해결

최종 background.js 파일은 다음과 같이 표시됩니다. 알림이 표시되지 않으면 Chrome 버전이 28 이상인지 확인하세요. 여전히 알림이 표시되지 않으면 DevTools 콘솔에서 기본 창 (마우스 오른쪽 버튼 클릭 > 요소 검사)과 백그라운드 페이지 (마우스 오른쪽 버튼 클릭 > 백그라운드 페이지 검사 검사)의 오류 메시지를 확인합니다.

추가 정보

이 단계에서 도입된 일부 API에 관한 자세한 내용은 다음을 참고하세요.

다음 단계로 진행할 준비가 되셨나요? 4단계 - WebView로 외부 링크 열기 »로 이동합니다.