[h3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

66
하이브리드 앱 제작 사례 공유 푸딩얼굴인식 3.0 앱스프레소랩 | 박종순 1 121029월요일

Upload: kth-

Post on 18-Dec-2014

3.852 views

Category:

Documents


0 download

DESCRIPTION

H3 2012 발표자료 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0 -KTH 박종순

TRANSCRIPT

Page 1: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

하이브리드앱 제작 사례 공유푸딩얼굴인식 3.0앱스프레소랩 | 박종순

112년 10월 29일 월요일

Page 2: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

Agenda

1. 하이브리드 앱과 프레임워크들

2. 단일페이지 인터페이스

3. 푸딩 얼굴인식 3.0 기술요소Javascript LibraryAppspresso Built-in APICustom Plugins

4. 실전 앱 제작 테크닉“웹 개발”스러운 “앱 개발” - 앱스프레소 On The FlyFast button clickiScroll 터치 이벤트 처리를 위한 레퍼button 이벤트를 담당하는 하나의 이벤트 delegate초기 앱 로딩 속도 개선...

212년 10월 29일 월요일

Page 3: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

하이브리드 앱과 프레임워크들

하이브리드 앱 프레임워크

Javascript Framework

312년 10월 29일 월요일

Page 4: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

PhoneGap, Appcelerator, Appspresso

플랫폼(iOS/Android/Etc.) 별 앱 빌드기능 제공

카메라 등 장치 접근을 위한 Device API 제공

하이브리드 앱과 프레임워크들

하이브리드 앱 프레임워크

412년 10월 29일 월요일

Page 5: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

하이브리드 앱과 프레임워크들

Javascript Framework

5

jQueryMobile, Sencha Touch, JQTocuh, Jo

모바일 웹브라우저용 웹앱 제작을 위한 프레임워크

순수 웹 기반 (카메라 등 장치접근 불가)

12년 10월 29일 월요일

Page 6: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

단일 페이지 인터페이스

단일 페이지 인터페이스 (SPI: Single page interface)

6

show/hide

하나의 HTML파일로 페이지 구성12년 10월 29일 월요일

Page 7: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

푸딩 얼굴인식 3.0 기술요소

7

Javascript Library

앱스프레소 내장 API

앱스프레소 커스텀 플러그인

12년 10월 29일 월요일

Page 8: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

jQuery 1.6

xx - 자체 제작 페이지 라이브러리기존 플랫폼: 퍼포먼스 이슈, 커스터마이징 어려움

iScroll4

jpeg encoderAndroid Canvas를 이미지 파일로 저장하기 위함

oauth.js, sha1.jsFacebook, Twitter OAuth 인증용

푸딩 얼굴인식 3.0 기술요소

Javascript Library

8

AppspressoKitchenSink소스코드 공개

12년 10월 29일 월요일

Page 9: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

filesystemdevice status

푸딩 얼굴인식 3.0 기술요소

Built-in Plugin

9

ax.ext.iosax.ext.androidax.ext.gaax.ext.mediaax.ext.netax.ext.ui

- 히스토리 이미지, json파일저장 등 - 네트워크 상태 체크 등

- iOS 고유 네이티브 API - Android 고유 네이티브 API- Google Analytics API - 화면캡쳐 API - cross domain 우회용 네트워크 API- 네이티브 다이얼로그 API

12년 10월 29일 월요일

Page 10: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

iOS / Android Camera

Push notification

Admob

Media Share - 카카오톡 등 공유

etc...

푸딩 얼굴인식 3.0 기술요소

Custom Plugin

1012년 10월 29일 월요일

Page 11: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

11

실전 앱 제작 테크닉1. 하이브리드앱 주의사항2. “웹 개발”스러운 “앱 개발” - On The Fly3. Fast button click4. iScroll 터치 이벤트 처리를 위한 레퍼5. 버튼 이벤트는 한곳에 모아 처리6. 초기 앱 구동 속도 개선7. 페이지 전환 효과8. DEMO9. CSS 개발자 협업10.다국어 처리11.파일시스템 레퍼

12년 10월 29일 월요일

Page 12: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

하이브리드 앱 주의사항

1212년 10월 29일 월요일

Page 13: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

12년 10월 29일 월요일

Page 14: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

12년 10월 29일 월요일

Page 15: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

하이브리드 앱 주의사항

그래서 어떻게??

15

가능한 모든 리소스는 앱에 포함

오프라인 대응

꼭 필요한 경우에만 웹 리소스 접근

네이티브 앱 UI/UX 구현

12년 10월 29일 월요일

Page 16: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

“웹 개발”스러운 “앱 개발”

16

앱스프레소 On The Fly

12년 10월 29일 월요일

Page 17: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

“웹 개발”스러운 “앱 개발” - On The Fly

앱 개발 사이클

17

코딩

개발자

컴파일설치 및 확인

12년 10월 29일 월요일

Page 18: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

“웹 개발”스러운 “앱 개발” - On The Fly

왜그럴까요??

18

코드 한줄을 수정해도 컴파일 필요웹 개발에 익숙한 개발자들은 적응안됨참을 수 없는 컴파일 과정의 답답함

코드수정 > 새로고침 되게 해주세요!!!

12년 10월 29일 월요일

Page 19: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

“웹 개발”스러운 “앱 개발” - On The Fly

On The Fly 앱 개발 사이클

19

코딩

확인리플래쉬

12년 10월 29일 월요일

Page 20: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

“웹 개발”스러운 “앱 개발” - On The Fly

20

http://appspresso.com

12년 10월 29일 월요일

Page 21: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

Fast button click터치 반응성 향상 기법

2112년 10월 29일 월요일

Page 22: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

12년 10월 29일 월요일

Page 23: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

Click event VS Touch event

브라우저는 터치이벤트인지를 판단할 시간이 필요

약 300ms 의 delay time

https://developers.google.com/mobile/articles/fast_buttons

http://cubiq.org/remove-onclick-delay-on-webkit-for-iphone

Fast button click - 터치 반응성 향상 기법

왜그럴까요??

2312년 10월 29일 월요일

Page 24: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

var  touchEvent  =  ‘touchstart’;

//  touch  event를  지원하지  않는  브라우저에서는  mousedown을  이용if  (typeof  document.body.ontouchstart  ===  'undefined'  )  {          touchEvent  =  ‘mousedown’;}document.getElementById(‘someElement’)      .addEventListener(touchEvent,  function(e){        //  do  something},  false);

Fast button click - 터치 반응성 향상 기법

이렇게 해결했습니다

24

touchstart사용

12년 10월 29일 월요일

Page 25: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

iScroll 터치 이벤트 처리를 위한 레퍼

2512년 10월 29일 월요일

Page 26: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

헤더고정 바디영역 스크롤 지원회전목마(Carousel) 지원iOS/Android 모두 지원크로스플랫폼 스크롤 library 중 가장 빠른 속도

iScroll 터치 이벤트 처리를 위한 레퍼

iScroll

26

터치이벤트 처리의 어려움플랫폼에 따른 옵션변경 필요

12년 10월 29일 월요일

Page 27: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

touchTime을 계산하여 300ms 미만인 경우 클릭을 위한 터치이벤트로 간주iScroll 직접수정 대신 wrapper 모듈 작성 - xx.scroll개발자는 new iScroll(args) 대신xx.scroll.addScroll(args) 사용클릭을 위한 터치이벤트에 대해서만 onTouchEnd 콜백 호출플랫폼 별 옵션 분기처리 자동화

iScroll 터치 이벤트 처리를 위한 레퍼

이렇게 해결했습니다

2712년 10월 29일 월요일

Page 28: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

var  touchTime  =  0,        touchStart  =  0,        isScrolling  =  false;

document.addEventListener('DOMContentLoaded',  function(){        var  body  =  document.body;

       body.addEventListener(‘touchstart’,  function(e){                touchStart  =  new  Date().getTime();        },  false);

       body.addEventListener(‘touchmove’,  function(e){                isScrolling  =  true;        },  false);

       body.addEventListener(‘touchend’,  function(e){                isScrolling  =  false;        },  false);});

var  myScroll  = new iScroll(‘scrollWrapper’, {        ...,        onBeforeScrollEnd: function(){ touchTime = (new Date().getTime()) - touchStart; }, onTouchEnd: onTouchEnd,        ...});

...

iScroll 터치 이벤트 처리를 위한 레퍼

touchTime 계산

28

var  myScroll  = new iScroll(‘scrollWrapper’, {        ...,        onBeforeScrollEnd: function(){ touchTime = (new Date().getTime()) - touchStart; }, onTouchEnd: onTouchEnd,        ...});

var  touchTime  =  0,        touchStart  =  0,        isScrolling  =  false;

document.addEventListener('DOMContentLoaded',  function(){        var  body  =  document.body;

       body.addEventListener(‘touchstart’,  function(e){                touchStart  =  new  Date().getTime();        },  false);

       body.addEventListener(‘touchmove’,  function(e){                isScrolling  =  true;        },  false);

       body.addEventListener(‘touchend’,  function(e){                isScrolling  =  false;        },  false);});

12년 10월 29일 월요일

Page 29: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

function  onTouchEnd(e){        var  args  =  this.args,                target  =  e.target,                eventPage,                i  =  10;

       if  (isScrolling)  {                isScrolling  =  false;        }  else  {                while  (i-­‐-­‐)  {                        if($(target).hasClass('page'))  {                                eventPage  =  $(target).attr('id');                                break;                        }                        target  =  target.parentNode;                }

               if  (!xx.page[eventPage]  ||  xx.page[eventPage].info.isShown)  {                        if(touchTime  <  300  &&  touchTime  >  1)  {                                if  (args.onTouchEnd)  {  args.onTouchEnd(e);  }                        }                }        }}

iScroll 터치 이벤트 처리를 위한 레퍼

클릭을 위한 터치이벤트 판단

29

300ms이상인 경우만버튼 이벤트

12년 10월 29일 월요일

Page 30: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

iScroll 터치 이벤트 처리를 위한 레퍼

푸딩얼굴인식 3.0 사용 예

30

var  onOptionTouchEnd  =  function(e)  {        //  클릭이라  판단된  경우에만  호출됨        //  do  something};

if(typeof  xx.scroll.wrapperSetting  ===  'undefined'){        var  scrollOption  =  {                  wrapperId:  'wrapperSetting',                scrollbarClass:  'noScroll',                onTouchEnd:  onOptionTouchEnd        };            xx.scroll.addScroll(scrollOption);}

12년 10월 29일 월요일

Page 31: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

버튼 이벤트는 한곳에 모아 처리

3112년 10월 29일 월요일

Page 32: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

document.getElementById(‘someElement’)      .addEventListener(‘touchstart’,  function(e){        //  do  something},  false);

$(‘#someElement’).bind(‘click’,  function(e){        //  do  something},  false);

<div  onclick=‘alert(“aa”);’>BUTTON</div>

버튼 이벤트는 한곳에 모아 처리

일반적인 이벤트 처리

3212년 10월 29일 월요일

Page 33: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

<div class="header">

<button data-role="button" title="btnSettings" class="back"> <img src="image/icon_option.png" alt="setting" /> <div class="imgfix">&nbsp;</div> <span class="bg"></span> <img class="new hide" src="image/main_btn_new.png" alt="new" /> </button> <div class="title"> <h1><img id="mainTitle" src="image/beacon.png" alt="얼굴인식"/></h1> <div class="imgfix">&nbsp;</div> </div>

<button data-role="button" title="btnMy" class="login"> <img src="image/icon_login.png" alt="my" /> <div class="imgfix">&nbsp;</div> <span class="bg"></span> </button></div>

버튼 이벤트는 한곳에 모아 처리

버튼 HTML

33

<div class="header">

<button data-role="button" title="btnSettings" class="back"> <img src="image/icon_option.png" alt="setting" /> <div class="imgfix">&nbsp;</div> <span class="bg"></span> <img class="new hide" src="image/main_btn_new.png" alt="new" /> </button> <div class="title"> <h1><img id="mainTitle" src="image/beacon.png" alt="얼굴인식"/></h1> <div class="imgfix">&nbsp;</div> </div>

<button data-role="button" title="btnMy" class="login"> <img src="image/icon_login.png" alt="my" /> <div class="imgfix">&nbsp;</div> <span class="bg"></span> </button></div>

12년 10월 29일 월요일

Page 34: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

document.body.addEventListener('touchstart',  function(e)  {        var  target  =  e.target,                btnName,����������� ������������������  eventPage,����������� ������������������  i  =  10;

       while(i-­‐-­‐)  {                if($(target).attr('data-­‐role')  ===  'button')  {  i  =  10;����������� ������������������  break;����������� ������������������  }                target  =  target.parentNode;        }

       if  (target.getAttribute('data-­‐role')  ===  'button')  {

               btnName  =  $(target).attr('title');                $(target).addClass('pressed');

               setTimeout(function()  {                        $(target).removeClass('pressed');

                       while  (i-­‐-­‐)  {                                if($(target).hasClass('page'))  {                                        eventPage  =  $(target).attr('id');����������� ������������������  break;                                }                                target  =  target.parentNode;                        }

                       if  (_DEBUG)  {  console.log('touch  action:',  eventPage,  btnName);  }                        onButtonTouched(btnName,  eventPage);

               },  200);

               e.stopPropagation();                e.preventDefault();        }},  false);

버튼 이벤트는 한곳에 모아 처리

하나의 이벤트 delegate

34

document.body.addEventListener('touchstart',  function(e)  {        var  target  =  e.target,                btnName,����������� ������������������  eventPage,����������� ������������������  i  =  10;

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  //  실제  버튼  element  찾기        while(i-­‐-­‐)  {                if($(target).attr('data-­‐role')  ===  'button')  {                        i  =  10;����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  break;����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  }                target  =  target.parentNode;        }

     if  (target.getAttribute('data-­‐role')  ===  'button')  {

               //  버튼  이름  가져오기                                btnName  =  $(target).attr('title');

               //  버튼  누름효과를  위한  pressed  class추가                $(target).addClass('pressed');

setTimeout(function()  {      //  버튼  누름효과  제거      $(target).removeClass('pressed');

     while  (i-­‐-­‐)  {    //  이벤트가  발생한  페이지  찾기              if($(target).hasClass('page'))  {                      eventPage  =  $(target).attr('id');����������� ������������������  break;              }              target  =  target.parentNode;      }      if  (_DEBUG)  {            console.log('touch  action:',  eventPage,  btnName);        }      onButtonTouched(btnName,  eventPage);},  200);

12년 10월 29일 월요일

Page 35: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

var  _btnGlobalTouchActionFlag  =  false,        _btnGlobalTouchActionTimer  =  undefined;

function  onButtonTouched(btnName,  eventPage)  {        if  (_btnGlobalTouchActionFlag  ===  true)  {                if  (_DEBUG)  {  console.log('두번  터치된  경우입니다!!!',  btnName,  eventPage);  }

               if  (_btnGlobalTouchActionTimer  !==  undefined)  {                        g.clearTimeout(_btnGlobalTouchActionTimer);                }

               _btnGlobalTouchActionTimer  =  setTimeout(function(){                        _btnGlobalTouchActionFlag  =  false;                        _btnGlobalTouchActionTimer  =  undefined;                },  1000);

               return;        }

       switch(btnName)  {      //  basic  button        case  'btnMy':                xx.page.pageMy.show();                break;        case  'btnSettings':                //  이건  중복  터치가  자주  일어  나므로  중복  터치  방지                _btnGlobalTouchActionFlag  =  true;                xx.page.pageSetting.show();                break;        case  'btnBack':        case  'btnClose':                xx.page.back();                break;        }����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ...

버튼 이벤트는 한곳에 모아 처리

onButtonTouched - 1

35

 case  'btnSettings':                //  이건  중복  터치가  자주  일어  나므로  중복  터치  방지                _btnGlobalTouchActionFlag  =  true;                xx.page.pageSetting.show();                break;

//  중복  터치이벤트  방지를  위한  변수var  _btnGlobalTouchActionFlag  =  false,        _btnGlobalTouchActionTimer  =  undefined;

//  “버튼이름”  과  이벤트가  발생한  “페이지이름”을  전달  받음function  onButtonTouched(btnName,  eventPage)  {      ...

if  (_btnGlobalTouchActionFlag  ===  true)  {        if  (_DEBUG)  {                  console.log('두번  터치된  경우입니다!!!');          }                          if  (_btnGlobalTouchActionTimer  !==  undefined)  {                g.clearTimeout(_btnGlobalTouchActionTimer);        }        _btnGlobalTouchActionTimer  =  setTimeout(function(){                _btnGlobalTouchActionFlag  =  false;                _btnGlobalTouchActionTimer  =  undefined;        },  1000);

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  //  플래그가  켜진  경우  이벤트  처리안하고  return        return;}

12년 10월 29일 월요일

Page 36: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

버튼 이벤트는 한곳에 모아 처리

onButtonTouched - 2

36

       ...

       switch  (eventPage)  {        case  'pageMain':                switch  (btnName)  {                        case  'btnFind':                                xx.page.pageFind.show();                                break;                        case  'btnBattle':                                xx.page.pageBattle.show();                                break;                }                break;        case  '...':

       }

       if  (_btnGlobalTouchActionFlag  ===  true)  {                _btnGlobalTouchActionTimer  =  setTimeout(function(){                        _btnGlobalTouchActionFlag  =  false;                        _btnGlobalTouchActionTimer  =  undefined;                },  1000);        }}

 switch  (eventPage)  {  //  이벤트  페이지에  따라  분기  처리        case  'pageMain':              switch  (btnName)  {  //  버튼  이름에  따라  분기  처리                          case  'btnFind':                                xx.page.pageFind.show();                                break;                        case  'btnBattle':                                xx.page.pageBattle.show();                                break;                }                break;        case  'pageBattle':                //  do  something                break;

//  중복  이벤트방지  플래그가  켜진  경우  1추  후  플래그  해지if  (_btnGlobalTouchActionFlag  ===  true)  {        _btnGlobalTouchActionTimer  =  setTimeout(function(){                _btnGlobalTouchActionFlag  =  false;                _btnGlobalTouchActionTimer  =  undefined;        },  1000);}

12년 10월 29일 월요일

Page 37: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

하나의 이벤트 리스너 정의앱 전역에 걸친 일관된 이벤트 처리CSS 개발과 무관한 버튼 액션 처리버튼누름 효과 처리 자동화이벤트 코드를 한곳에 모음으로서 유지보수 용이

버튼 이벤트는 한곳에 모아 처리

효과

3712년 10월 29일 월요일

Page 38: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

초기 앱 구동 속도 개선

3812년 10월 29일 월요일

Page 39: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

단일페이지 인터페이스로 구성된 앱

페이지 리소스는 앱 구동시에 로딩?

jQueryMobile의 멀티페이지 템플릿

초기 앱 구동 속도 개선

하이브리드 앱은 느려요~

39

리소스의 lazy loading이 답이다!

12년 10월 29일 월요일

Page 40: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

<!-- main page --><div id="pageMain" class="page" style="display: none;"> <div class="header"> ... <img class="new hide" src="image/main_btn_new.png" alt="new" /> ... <img class="main_event_ball1" src="locales/ko/image/main_event1.png"/> <img class="hide main_event_ball2" src="locales/ko/image/main_event2.png"/> <img class="hide main_event_ball1" src="locales/ko/image/main_event1.png"/> <img class="hide main_event_ball2" src="locales/ko/image/main_event2.png"/> <div class="imgfix">&nbsp;</div> ... </div> <div class="body"> ... <img class="type1 o1" src="locales/ko/image/main_frame03.png"/> <img class="type1 o2" src="locales/ko/image/main_frame04.png"/> ... </div></div>

<!-- page pageFind --><div id="pageFind" class="page hide ui"> <img src="image/find_guide1.png" alt="선글라스NO" /> ... <img src="image/find_guide2.png" alt="모자NO" /> ... <img src="image/find_guide3.png" alt="옆모습NO" /></div> ...

초기 앱 구동 속도 개선

싱글 페이지 템플릿

40

<!-- page pageBattleSearch --><div id="pageBattleSearch" class="page hide ui"> ... <img src="image/find_icon_guide.png" /> ... <img src="image/battle_guide1.png" /> <img src="image/battle_guide_icon.png" /> <img src="locales/ko/image/battle_guide2.png"/> <img src="image/battle_guide_icon.png" /> <img src="image/battle_guide3.png" /> ...</div>

메인 페이지

서브1서브2

12년 10월 29일 월요일

Page 41: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

앱 실행시 불필요한 리소스 Lazy Loadingimage, javascript, html 은 모두 Lazy Loading(단, CSS는 앱 시작시 full loading)

멀티페이지 템플릿, 페이지 모듈 JS 분리

Lazy Loading을 담당하는 xx.page 라이브러리(개발자와 사용자는 Lazy Loading이 되는지도 몰라요)

초기 앱 구동 속도 개선

이렇게 해결했습니다

4112년 10월 29일 월요일

Page 42: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

<!-- main page --><div id="pageMain" class="page" style="display: none;"> <div class="header"> ... <img class="new hide" src="image/main_btn_new.png" alt="new" /> ... <img class="main_event_ball1" src="locales/ko/image/main_event1.png"/> <img class="hide main_event_ball2" src="locales/ko/image/main_event2.png"/> <img class="hide main_event_ball1" src="locales/ko/image/main_event1.png"/> <img class="hide main_event_ball2" src="locales/ko/image/main_event2.png"/> <div class="imgfix">&nbsp;</div> ... </div> <div class="body"> ... <img class="type1 o1" src="locales/ko/image/main_frame03.png"/> <img class="type1 o2" src="locales/ko/image/main_frame04.png"/> ... </div></div>

<!-- page pageFind --><div id="pageFind" class="page hide ui"></div>

<!-- page whois (finding) --><div id="pageFinding" class="page hide"></div>

<!-- page whois result --><div id="pageFound" class="page hide ui"></div>

<!-- page pageBattle --><div id="pageBattle" class="page hide ui"></div>

<!-- page pageBattle --><div id="pageBattleResult" class="page hide ui"></div>

<!-- page pageBattleSearch --><div id="pageBattleSearch" class="page hide ui"></div>

<!-- page pageBattleSearchStar --><div id="pageBattleSearchStar" class="page hide ui"></div>

메인 페이지

<!-- page pageBattle --><div id="pageBattle" class="page hide ui"></div>

<!-- page pageBattle --><div id="pageBattleResult" class="page hide ui"></div>

<!-- page whois (finding) --><div id="pageFinding" class="page hide"></div>

<!-- page whois result --><div id="pageFound" class="page hide ui"></div>...

초기 앱 구동 속도 개선

42

멀티페이지 템플릿

HTML Javascript

12년 10월 29일 월요일

Page 43: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

if  (this.innerHTML  ===  '')  {        ...          var  targetHTML  =  arg.id  +  '.html?'  +  (new  Date().getTime());        if  (arg.useLocale  ===  true)  {                targetHTML  =  'locales/'  +  _lang  +  '/'  +  targetHTML;        }              //  내용이  없는  경우  ajax를  이용한  lazy  loading          $.ajax({                    url:  targetHTML,                    context:  body                }).done(function(data)  {                        $(self).html(data).after(function(){                                loadContentCallback();                        });                                });          ...  }

초기 앱 구동 속도 개선

43

HTML lazy loading

12년 10월 29일 월요일

Page 44: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

초기 앱 구동 속도 개선

44

<!-- page pageBattle --><div id="pageBattle" class="page hide ui"></div>

<!-- page pageBattle --><div id="pageBattleResult" class="page hide ui"></div>

<!-- page pageBattleSearch --><div id="pageBattleSearch" class="page hide ui"></div>

<!-- page pageBattleSearchStar --><div id="pageBattleSearchStar" class="page hide ui"></div>

Javascript lazy loadingfunction  addScript(url,  callback)  {        if  (_DEBUG)  {  console.log('addScript',  url);  }

       if  (typeof  lazyScriptLoading[url]  ===  'undefined')  {����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������        //  bookmarklet  기법을  활용한  스크립트  lazy  loading                (function(e)  {                        e.onload  =  callback;                        e.setAttribute("src",  url);                        document.getElementsByTagName("body")[0].appendChild(e);                }(document.createElement("script")));                lazyScriptLoading[url]  =  true;        }  else  {                if  (typeof  callback  ===  'function')  {                        callback();                }        }}

12년 10월 29일 월요일

Page 45: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

초기 앱 구동 속도 개선

45

<!-- page pageBattle --><div id="pageBattle" class="page hide ui"></div>

<!-- page pageBattle --><div id="pageBattleResult" class="page hide ui"></div>

<!-- page pageBattleSearch --><div id="pageBattleSearch" class="page hide ui"></div>

<!-- page pageBattleSearchStar --><div id="pageBattleSearchStar" class="page hide ui"></div>

푸딩얼굴인식 3.0 사용 예 - 1xx.page.add({ id: 'pageMy', onPageBeforeLoadForInit: function(){ var self = this; app.common.addScript('js/page_my.js', function(){ self.info.onPageLoad = function(){ app.pageMy.showScroll(); }; }); }, onPageHide: function() { app.pageMy.resetStatus(); }, useLocale: true});

12년 10월 29일 월요일

Page 46: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

초기 앱 구동 속도 개선

46

<!-- page pageBattle --><div id="pageBattle" class="page hide ui"></div>

<!-- page pageBattle --><div id="pageBattleResult" class="page hide ui"></div>

<!-- page pageBattleSearch --><div id="pageBattleSearch" class="page hide ui"></div>

<!-- page pageBattleSearchStar --><div id="pageBattleSearchStar" class="page hide ui"></div>

푸딩얼굴인식 3.0 사용 예 - 2xx.page.add({ id: 'pageSetting', onPageBeforeLoadForInit: function(){ var self = this; app.common.addScript('js/page_setting.js', function(){ self.info.onPageLoad = function(){ app.pageSetting.updateUI(); }; }); }, onPageBeforeHide: function(){ app.common.removeWebView(); }, type: 'vertical'});

12년 10월 29일 월요일

Page 47: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

네이티브앱 수준의 앱 시작 속도

앱 메모리 사용 최소화

멀티페이지 템플릿을 활용한 다국어 처리 용이

CSS 개발자와 협업 시 코드 충돌 최소화

초기 앱 구동 속도 개선

효과

4712년 10월 29일 월요일

Page 48: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

페이지 전환 효과

4812년 10월 29일 월요일

Page 49: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

페이지 전환 효과

HTML

49

<!-- page pageBattle --><div id="pageBattle" class="page ui">...</div>

<!-- page pageBattle --><div id="pageBattleResult" class="page ui">...</div>

<!-- page whois (finding) --><div id="pageFinding" class="page">...</div>

<!-- page whois result --><div id="pageFound" class="page ui">...</div>

12년 10월 29일 월요일

Page 50: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

페이지 전환 효과

CSS

50

.page{ width: 100%; height: 100%; left: 0; top: 0; position: absolute; overflow: hidden; opacity: 0; -webkit-transition: all 0.3s ease-out;}

.page{ width: 100%; height: 100%; left: 0; top: 0; position: absolute; overflow: hidden; opacity: 0; -webkit-transition: all 0.3s ease-out;}

12년 10월 29일 월요일

Page 51: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

페이지 전환 효과

Javascript

51

// 배틀페이지 보이기$('#pageBattle').css({opacity: 1});

// 배틀페이지 슬라이드 다운$('#pageBattle').css({top: window.innerHeight});

// 배틀페이지 슬라이드 업$('#pageBattle').css({top: 0});

-webkit-transition: all 0.3s ease-out;

12년 10월 29일 월요일

Page 53: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

DEMO

5312년 10월 29일 월요일

Page 54: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

CSS 개발자와 협업

5412년 10월 29일 월요일

Page 55: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

CSS 개발자와 협업

55

data-role=”button”<div data-role="button" title="btnBattle"> <img id="main_btn_frame3" class="type1 o1" src="locales/ko/image/main_frame03.png" alt="닮은꼴 배틀" /> <div class="imgfix">&nbsp;</div> <div class="tit t1"></div> <img id="main_btn_frame3_desc" class="battle-msg msg-left" src="locales/ko/image/main_battle_msg2.png" alt="누가 더 연예인을 닮았을까?" /></div><div data-role="button" title="btnFind"> <img id="main_btn_frame4" class="type1 o2" src="locales/ko/image/main_frame04.png" alt="닮은꼴연예인찾기" /> <div class="imgfix">&nbsp;</div> <div class="tit t2"></div></div>

12년 10월 29일 월요일

Page 56: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

data-role=”button” 을 이용하므로 하위 마크업과 무관한 버튼영역 처리멀티페이지 템플릿 사용을 통한 CSS 개발자와 협업 시 코드 충돌 최소화

CSS 개발자와 협업

효과

5612년 10월 29일 월요일

Page 57: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

다국어 처리

5712년 10월 29일 월요일

Page 58: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

W3C Widget 1.0 Spechttp://www.w3.org/TR/widgets/folder-based localization

다국어 처리

다국어 처리

5812년 10월 29일 월요일

Page 59: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

다국어 처리

59

folder-based localization

12년 10월 29일 월요일

Page 60: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

실전 앱 제작 테크닉

파일시스템 레퍼

6012년 10월 29일 월요일

Page 61: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

파일시스템 레퍼

파일시스템 레퍼 - 1

61

function  writeFile(path,  text,  isBase64,  scb,  ecb)  {        if  (!ax.util.isValidPath(path))  {                ecb(new  Error('invalid  file  path:'  +  path));                return;        }

       var  pos  =  path.lastIndexOf('/'),                folder  =  path.substring(0,  pos),                filename  =  path.substring(pos  +  1,  path.length);

       if  (_DEBUG)  {  console.log(_module_name,  'writeFile',  folder,  filename);  }

       var  writeStream  =  function(stream){                if  (isBase64)  {                        stream.writeBase64(text.toString());                }  else  {                        if  (_DEBUG)  {  console.log(_module_name,  'write  text:',  text);  }                        stream.write(text.toString());                }                stream.close();                if  (scb)  {  scb();  }        };        ...}

12년 10월 29일 월요일

Page 62: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

파일시스템 레퍼

파일시스템 레퍼 - 2

62

function  writeFile(path,  text,  isBase64,  scb,  ecb)  {        ...

       deviceapis.filesystem.resolve(                function(dir){                        dir.listFiles(function(files){                                var  i=0,  len  =  files.length,  f;                                for(i=0;  i<len;  i++)  {                                        f  =  files[i];                                        if  (f.name  ===  filename)  {                                                f.openStream(writeStream,  ecb,  "w",  "utf-­‐8");                                                return;                                        }                                }                                var  newFile  =  dir.createFile(filename);                                newFile.openStream(writeStream,  ecb,  "w",  "utf-­‐8");                        },  ecb);                },  ecb,  folder,    'rw'        );}

12년 10월 29일 월요일

Page 63: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

개발시 손쉬운 FileSystem 접근xx.fexplorer 모듈을 활용한 파일시스템 브라우징debug 시에만 파일 브라우저 이용

파일시스템 레퍼

효과

6312년 10월 29일 월요일

Page 64: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

Q&A

64

Q&A

12년 10월 29일 월요일

Page 65: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

참조

참조

65

http://phonegap.comhttp://www.appcelerator.comhttp://appspresso.comhttp://jquerymobile.comhttp://www.sencha.comhttp://jqtouch.comhttp://joapp.comhttp://enable-cors.orghttp://msdn.microsoft.com/ko-kr/magazine/cc507641.aspxhttp://iolothebard.tistory.com/496http://appspresso.com/api/extension/symbols/ax.ext.net.CurlOpts.htmlhttp://appspresso.com/ko/api-reference-kohttp://appspresso.com/ko/archives/4098 https://developers.google.com/mobile/articles/fast_buttonshttp://cubiq.org/remove-onclick-delay-on-webkit-for-iphonehttp://h3.paran.com/2011/session/hybrid-app-architecture-and-development-method.htmlhttp://www.w3.org/TR/widgets/http://www.bytestrom.eu/blog/2009/1120a_jpeg_encoder_for_javascript

12년 10월 29일 월요일

Page 66: [H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0

감사합니다.개발실 / 앱스프레소팀 과장 / 박종순

[email protected]@althjs

6612년 10월 29일 월요일