[HTML5] Notifications (알림)

Posted in 모바일/HTML5 // Posted at 2010. 8. 30. 17:57
728x90
데스크탑 알림 창
응용프로그램에서 알림창은 (응용프로그램) 자신의 상태나 변화를 실시간으로 알려주기 위한 장치이다
대표적인 예로 메신저에서 메시지 수신이나 친구 로그인 등의 알려주는 것을 들 수 있다


이러한 알림창은 응용프로그램이 비활성화 되어 있더라도,
사용자에게 중요한 정보를 시각적으로 즉시 알려 주기 위한 유용한 장치이다

HTML5 의 Notifications 은 웹 페이지에서도 이와 같은 데스크탑 알림창을 구현하기 위한 스펙이다

기존 윈도우 응용프로그램의 알림창과 같이, 데스크탑 화면 우측 하단에 작업표시줄 근처에 풍선말 형태로 출력된다. 즉 웹 페이지 범위를 벗어난 영역에 알림창이 표시되며 웹 페이지가 최소화 되어 있거나 비활성화 되어 있어도 상관없이 알림창은 동작한다

아래 화면은 Notifiactions 로 띄운 알림창을 구글 크롬에서 실행한 화면이다
(크롬)


지원되는 브라우저

현재 Notifications 는 Draft 상태로 HTML5 정식 스펙에 포함되지는 않은 듯 하다
구글이 제시한 스펙으로써 지원되는 브라우저 역시 구글 크롬에 한정되어 있다

따라서 현재 시점에 이 기술을 실 서비스에 접목시키기는 어려울 수 있으나 이 글에서는 간단한 사용법 정도를 숙지하는 것으로 하겠다

다시 말하지만, Notifactions 는 현재 구글 크롬 브라우저만 지원되고 있다


if(!!window.webkitNotifications) {
     alert("현재 브라우저는 Notifications를 지원합니다")
}
else{
      alert("현재 브라우저는Notifications를 지원하지 않습니다")
}


Notifications 이 자동알림의 전부는 아니다
간혹 HTML5의 Notifications 에 대한 오해가 있는 듯 하여 집고 넘어가고자 한다
Notification 이 알림창을 띄우는 것이다 보니 이 자체가 자동 알림을 구현하는 전부인 듯 오해를 하기 쉽다. 물론 이 기술이 응용되는 궁극적인 모습은 자동 알림인 것은 사실이지만, Notifications 만으로 자동알림을 구현할 수는 없다는 것을 말하고 싶다

이는 마치 오프라인 웹 응용프로그램 구현이 어플리케이션 캐시와 밀접하게 연관되어 있지만
Web Storage 나 Web SQL Database와 같은 로컬 저장소 기술과 접목해야한 제대로 된 오프라인 웹 응용프로그램이 될 수 있는 개념과 유사하다

다시 말해 웹 서비스에 있어, 알림 대상이 되는 내용 및 이벤트의 대부분은 웹 서버측에서 내려주는 시나리오가 많으며 이럴 경우 Ajax 를 통한 반복적인 비동기 폴링(polling)이나 HTML5의 새로운 스펙인 Server-Sent Events 와 같은 기술이 접목될 때 비로써 제대로 된 자동알림 구현이 가능하다는 것이다

물론 클라이언트의 데이터, 이벤트만을 기준으로 알림창을 띄우는 것이라면 Notifications와 적절한 스크립트의 조합만으로 가능하겠지만 대부분의 시나리오에서는 알림 대상이 되는 이벤트는 서버를 기준으로 발생하기 마련이다

따라서 'Notifications + 적절한 반복 스크립트 + 서버이벤트 감지' 기술 이 복합적으로 구현될 때 자동 알림이 완성된다고 할 수 있겠다


Notifications 다루기
그럼 지금부터 Notifications 의 기술적 구현을 간단히 살펴보자
Notifications 로 데스크탑 알림을 구현할 경우 다음의 절차를 따르는 것이 좋다

Notificatins API 지원 여부 확인 -> 사용자 승인 여부 확인 -> Notificatins 인스턴스 생성

Notificatins API 지원 여부 확인 
이 부분은 앞서 '브라우저 지원 현황' 에서 알아 본 것이다
window 전역 객체에 webkitNotifications 객체가 존재한다면 해당 브라우저는 Notificatins API를 지원 하고 있는 것이다

사용자 승인 여부 확인
사용자가 브라우저를 통해 웹 사이트를 볼 때 성가시거나(?) 보안에 위험이 있는 요소들은 사용자 승인과정을 따르게 되어 있다. 예를 들어 쿠키(Cookie)나 팝업 창의 경우 사용자가 활성화 여부를 결정할 수 있으며 HTML5 에서는 위치 정보 확인(Geolocation)과 같은 개인 정보 취득시 사용자 승인을 받도록 되어 있다. Notifications 역시 알림창을 띄울 것인지에 대한 사용자 승인 과정이 필요하다

이는 webkitNotifications 객체의 checkPermission() 함수로 확인 가능하다
이 함수의 반환 값은 0,1,2 중 하나인데 다음과 같다
0: 승인 됨, PERMISSION_ALLOWED
1: 승인 하지 않음, 승인 전, unknown, PERMISSION_NOT_ALLOWED
2: 거부 됨, PERMISSION_DENIED

Notificatins 인스턴스 생성
브라우저 지원 여부와 사용자 승인 여부의 확인 이후,
실제로 데스크탑 알림창을 띄우기 위해 Notificatins 인스턴스 생성해야 한다

Notificatins 인스턴스는 두 가지 버전으로 생성이 가능하다
createNotification(in DOMString iconUrl, in DOMString title, in DOMString body);
: 일반 텍스트 형식의 알림 창. 알림 창에 표현될 아이콘, 제목, 내용을 설정한다

createHTMLNotification(in DOMString url)
: HTML 형식의 알림 창. 알림 창에 표현될 유효한 웹 주소를 설정한다


Notifications 이벤트
Notifications 에는 알림창과 관련한 몇 가지 이벤트를 제공하고 있다
이 이벤트들을 이용하면 알림창이 표시될 때, 닫힐 때 특정 로직을 수행할 수 있다
Display 이벤트
: 알림창에 표시될 때 발생한다
  notification.ondisplay = function() { setTimeout(notification.cancel(), 15000); }

Close 이벤트
: 알림창에 닫힐 때 발생한다
  notification.onclose = function() { cancelReminders(event); }

Error 이벤트
 : 알림창과 관련한 오류가 있을 시 발생한다
   notification.onerror =function(e){ alert('error')};


Notifications 데모
Notifications 구현 절차에 따른 간단한 데모를 제작해 보자
두 가지 버전의 Notificatins 인스턴스를 생성하여 알림창을 동시에 띄우는 예제이다
그리고 브라우저 지원 여부와 사용자 승인 여부를 확인하고 알림 창을 띄우고 있다

<!DOCTYPE html>
<html>
<head></head>
<body>
  <button onclick="showNotification();">알림실행</button>
</body>
</html>
<script type="text/javascript">   
function showNotification(){
  if(!!window.webkitNotifications) { //브라우저 지원현황 확인하기
    if(window.webkitNotifications.checkPermission() == 0 ){ //사용자 승인 여부 확인하기 
      var picture = 'http://mkexdev.net/img/mkex.jpg';
      var titleStr = 'MKEX의 HTML5';
      var bodyStr = 'HTML5 Notification 데모입니다';     
      var noti1 = window.webkitNotifications.createNotification(picture, titleStr, bodyStr);
      var noti2 = window.webkitNotifications.createHTMLNotification("http://m.mkexdev.net");
      noti1.show();
      noti2.show();     
    }
    else{
     requestPermission(showNotification);
   }   
  }
  else{
    alert("현재 브라우저는Notifications를 지원하지 않습니다");
  }
}
function requestPermission (callback) {
  window.webkitNotifications.requestPermission(callback);
}
</script>



데모를 실행하면 최초 알림을 활성화 할지를 묻는 사용자 승인과정을 거친다
(이 데모는 mkexdev.net 도메인에서 서비스 되도록 하였다. 아래 승인에 해당 도메인에 대한 알림 승인 여부를 묻고 있다)


사용자가 승인하면 아래와 같이 데스크탑 우측 하단, 작업 표시줄 영역에 알림 창이 두개 생성된다
(구글 크롬)


참고: 한번에 표시되는 알림창의 갯수
데모에서 '알림실행' 버턴을 계속 클릭하면 그 만큼 알림창이 생성된다
그러나 한정된 화면을 가진 데스크탑에서 이것을 다, 한번에 표현하기는 힘들다

크롬 브라우저에서는 최대 5개까지 알림창을 동시에 띄우며 6개부터는 큐에 보관하여
다른 알림창에 숨겨졌을 때 하나씩 표시된다


참고: 트위터 최신 글 알림창
HTML5 Notifications 를 소개하는 외국 블로그를 보면 대부분 관련 데모로 트위터 최신글에 대한 알림창을 구현하고 있다.

트위터는 오픈API를 제공해 외부 개발자가 트위터 대부분의 기능을 사용할 수 있도록 하고 있다
데모에서는 트윝의 오픈 API를 이용해 Notifications 와 연동하는 구조이다

데모 URL: http://html5.firejune.com/demo/notification.html

소스의 핵심 부분을 잠깐 살펴 보자
function readTweets() {
  var username = document.getElementById('username').value;
  if (username == 'username') {
    alert('Enter a username first');
    return;
  }
  var script = document.createElement("script");
  script.src = 'http://twitter.com/statuses/user_timeline/'+ username+'.json?
                   count=1&callback=fetchTweets';
  document.body.appendChild(script);

}
function fetchTweets(data) {
  var tweet;
  var i = data.length;
  while (i--) {
    tweet = data[i];
    if (window.webkitNotifications.checkPermission() == 0) {      
      window.webkitNotifications.createNotification(tweet.user.profile_image_url,
                                                                      tweet.user.name, tweet.text).show();
    } else {      
      alert('You have to click on "Set notification permissions for this page" first to be able to
               receive notifications.');
      return;         
    }
  }
}

트위터에 특정 계정에 대한 최신 글을 불러오는 오픈 API를 다음과 같이 호출하고 있다
(사용자 계정 mkex , 글 수 1, 수신 콜백 함수 fetchTweets 지정)
script.src = 'http://twitter.com/statuses/user_timeline/mkex.json?count=1&callback=fetchTweets'; 

이렇게 호출하면 트위터 오픈 API는 JOSN 포맷의 데이터를 반환한다. 대략 다음과 같은 구조이다
[{"in_reply_to_screen_name":null,
 ....
"created_at":"Mon Aug 30 06:26:11 +0000 2010",
 ....
"source":"web","place":null,"contributors":null,
"geo":null,"retweeted":false,"coordinates":null,
"user":{
  "statuses_count":35,"profile_sidebar_border_color":"87bc44",
  "description":"Programmer ","screen_name":"mkex",
  ......  "profile_image_url":"http://a0.twimg.com/profile_images/1037935868/mkex_naver.com_9652dc86_normal.bmp",
  "id":161155360,"listed_count":6,"utc_offset":null,"followers_count":30,
  "url":"http://mkexdev.net"
  },
  "favorited":false,"id":22502412596,
  "text":"HTML5 \ub3d9\uc601\uc0c1 \ud45..... ....4\ub8cc\ub85c \uc804\ud658\u2026\uc65c? http://is.gd/eJgps"
}]


그리고 Notifications를 이용해 트위터 내용을 알림 창에 표시하고 있다
트위터 오픈API가 반환한 JSON 구조에서 프로필이미지와 이름, 글 내용을 알림창에 표시한다
window.webkitNotifications.createNotification(tweet.user.profile_image_url,tweet.user.name, tweet.text).show(); 


참고 자료>
http://dev.w3.org/2006/webapi/WebNotifications/publish/#requirements
http://html5.firejune.com/doc.html#notification
http://www.chromium.org/developers/design-documents/desktop-notifications/api-specification
http://www.html5rocks.com/tutorials/notifications/quick/