센차 터치(sencha touch) 2 핵심 가이드(Sencha SDK Tools) 마소 연재입니다.


마소 연재를 하였습니다.

주제는 : 센차 터치 2 핵심 가이드

 

 

http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=41056

COVER STORY

피할 수 없는 선택
정보보호

1부 | 법과 정책으로 본 정보보호의 현주소 | 전주현    120
2부 | 엔터프라이즈 환경을 위한 정보보호 | 성장열    124
3부 | 스마트 시대 달라지는 데이터베이스 정보보호 | 김형훈   128
4부 | 게임 산업에서의 정보보호의 의미와 이슈 | 강병탁    134
5부 | 로그인 보안 프로세스의 구성과 구축 | 한주성    138

INFORMATION

마소지기|열린 결말 │전도영 편집장      63
기자수첩|본질에 대한 이해 없는 막무가내 규제 버려야│이병혁 기자  65
MASO news|드디어 배일 벗은 아이폰5 외      66
Hardware Review|WD 레드 WD20EFRX 외      92
Books Review|HTML5 게임 프로그래밍 외      112
Column & Interview

Interview|염동훈 구글코리아 대표 │심정선 기자     72
김준수 부산정보산업진흥원 IT사업부장 │한종진 기자    74
데이비드 A. 차파 퀀텀 CTE │조수현 기자      76
컨퍼런스 취재 | 애자일 코리아 컨퍼런스 2012 | 한종진 기자   80
안랩 코어 2012 | 이병혁 기자       82
2012 IT 엑스포 부산 | 한종진 기자      84
법률사무소 민후의 SW 이야기 | 소프트웨어 공유의 문제점    81
소프트웨어 개발비를 손해배상 청구하는 산정법     83
공개SW 활용 성공사례│LG유플러스 │이병혁 기자     86
KINX │조수현 기자        88
텔레칩스 │조수현 기자        90
개발자가 만난 사람|최고를 만들기 위해 우직하게 걷고 있는 DBMS 개발자 |용영환 96
The War of IT|이순신과 한산도 대첩|김영옥     98
아키텍트 & 이노베이터 | 국내 의료정보화는 왜 실패했는가? | 신현묵  102
굿모닝 헬스| “목 디스크 수술이 무섭고 두려워요!” │ 모커리한방병원  105
수퍼개발자의 꿈| “원하면 노력하고 바라면 꿈을 꿔라” | 김지웅   106
여행이야기|네가지 없는 여행객, 이러면 아니 아니 되오 | 월간 여행스케치  110
패턴 이야기 | 플러그인 패턴(1) | ???      142
IT Certificate| IT 감사와 내부감사 │ 조희준     146
Developer Works | SNS와 연계된 홈오토메이션 개발 │ 최재규   150
IT 비즈니스 | BUX가 기업에 주는 가치 | 김영현     180
네트워크 이야기 | NTP와 로그 설정 | 박상철     184
Focus On | 심리적 보상의 메커니즘 | 박범진     188
마소플러스 | 개발자의 적 버그, 이렇게 잡자 | 허국현    206
Special Report

C++ 중심의 혁신이 시작됐다
비주얼 스튜디오 2012

1부 | 개발자의 르네상스를 꿈꾼다, 비주얼 스튜디오 2012 | 조성우   158
2부 | 비주얼 C++11에서의 C++11  | 최흥배     160
3부 | C++를 활용한 윈도우8 앱 개발 | 엄준일|     162
4부 | 병렬 프로그래밍 혁신, C++ AMP | 조진현     164
5부 | 비주얼 스튜디오 2012 테스트 익스플로러 활용 | 신영진   168
6부 | 현대화된 드라이버 개발 | 김성은      174
Smart & Mobile

아이클라우드를 활용한 앱 개발 │ 안진섭      194
아이클라우드를 이용한 맥 앱 만들기 (2)
S펜 SDK를 활용한 갤럭시 노트 애플리케이션 개발 │ 이원희 외    200
갤럭시 노트 애플리케이션 개발 실전 프로젝트
실전강의실

누구나 쉽게 구축할 수 있는 하둡 기반 분산시스템 | 이지훈   208
아파치 하둡을 활용한 로그 저장 및 처리
센차 터치 2 핵심 가이드 | 안병도      216
센차 SDK 툴
Cilk Plus 병렬 프로그래밍 | 고형호      222
인텔 패러럴 어드바이저와 함께하는 Cilk Plus – 루프 병렬성
Play! 프레임워크와 함께 하는 즐거운 웹 개발 | 김용웅 외    228
Play! 프레임워크로 상용 서비스 개발하기
모바일 및 데스크톱PC를 위한 가볍고 빠른 GUI 툴킷 EFL | 박춘언 외  234
EFL 핵심 기능 알아보기
질의응답 사이트 예제로 배우는 ASP.NET MVC3 | 허국현    240
WYSIWYG 에디터 장착
MASO 캠퍼스

캠퍼스 소식 | 교육과학기술부, 과학-비즈니스 융합 전문가 양성한다 외  246
IT JOB Trend | 직장인 52.3%, “현재 자기계발 중” | 잡코리아   248
자기계발가이드 | 제 5회 대학생 전력기술 아이디어 공모전 외   249
네 꿈을 펼쳐라!| 숭실대학교 구글개발자그룹 | 심정선 기자   250

스텝 바이 스텝

data-p로 열어가는 새로운 세상 | 최시영      252
새로운 범용 프로그래밍 언어, data-p
자바카페와 함께하는 웹 기초 강좌 | 이은미     258
JSP(Java Server Page) 활용하기
DBMS

뉴스│한국정보화진흥원, 공공 데이터 품질관리 위한 커뮤니티 발족 외  266
컬럼│
엑시엄이 보는 DB 세상 | 이현희       268
Large Object – LOB의 저장방식 및 사용법
리포트│
퀴즈로 배우는 SQL | 기민용       270
숫자를 영문으로 표기하기
개발자가 꼭 알아야할 데이터베이스 지식 | 임주한     274
DB2 레인지 파티션의 실전 적용
퀴즈이벤트         116
독자가 편집자에게        156
미리 보는 11월호         192
게시판           264
정기구독 안내         280
이 달의 디스켓 http://www.imaso.co.kr
실전강의실 | Play! 프레임워크로 상용 서비스 개발하기 | 김용웅 외  228
EFL 핵심 기능 알아보기 | 박춘언 외     234
스텝바이스텝 │ Java Server Page 활용하기 │ 이은미    258

Trailing comma is not legal in an ECMA-262 object initializer


sencha touch 2.1 beta3 에서 sencha app build native로 네이티브 앱 생성 시, 다음과 같은 에러가 발생하는 경우는

[WARN ] JsParse Warning :
message => Trailing comma is not legal in an ECMA-262 object initializer
file => /Users/yaioyaio/Sites/SenchaProject2.1/SnsPop/app.js:36,5

line => ],

js 파일의 코딩에서 마지막 값이 없는데 “콤마”가 있는 경우 경고가 발생한다.

sencha touch 2..0.x.x 버전에서 발생 하지 않던 경고이다.

즉,

views: [
‘Main’,
]

또는

{xtype: ‘main1’},
{xtype: ‘main2’},
{xtype: ‘main3’},

인 경우 마지막 값이 없는데 “콤마”가 있으면 안된다.

아직은 베타라 그런것인지는 모르겠다.

sencha touch 2.1 rc1 sencha cmd 3.0.0.188


sencha touch 2.1 rc1 sencha cmd 3.0.0.188

 

다음의 내용은 새롭게 업그레이드 된 버전을 가지고 간단한 테스트 작업을 해 보는 것이다. 아직은 베타 버전이므로 모든 프로젝트에 적용하는 것은 아직은 시기상조이므로 이점은 분명 알고 테스트를 하기 바란다. 다만, 조금 더 좋아진 환경을 확인 하는 것으로 만족을 해야 한다.

 

그럼 본격적으로 테스트를 해 보는 과정을 알아 보자.

 

 

첫 번째. 다운로드 및 압축 해제와 폴더 복사.

 

http://www.sencha.com/forum/announcement.php?f=92&a=36

 

위의 사이트를 접속 하여 각 OS에 맞는 파일을 다운로드 받는다.

 

다운 받은 파일은 <그림 1>과 같이 2가지이다.

 

<그림 1>다운로드 파일.

 

다운로드 받은 파일 중 SenchaCmd-3.0.0.188-osx.app.zip 파일을 압축 해제 한다. 해제한 파일을 설치한다.

 

<그림 2>는 SenchaCmd-3.0.0.188을 설치한 내용을 터미널에서 본 내용이다. 그리고 <그림 3>은 파인더에서 생성된 폴더 구조를 확인한 것이다.

 

<그림 2> SenchaCmd-3.0.0.188 터미널에서 확인.

 

<그림 3> SenchaCmd-3.0.0.188 파인더에서 확인.

지금까지 SenchaCmd-3.0.0.188 설치를 하였고, 설치된 내용을 <그림 2>와 <그림 3>을 통해서 확인 하였다. 다음은 sencha touch 2.1-rc1 버전을 설치할 차례이다.

 

다운 받은 sencha-touch-2.1.0-rc1.zip 파일을 압축 해제 한다. 압축 해제한 폴더를 복사 하여 지금까지 sencha touch 작업하던 폴더와 다른 곳에 붙여 넣기를 한다. 본인의 경우는 <그림 4>와 같다.

 

<그림 4> sencha touch 2.1 rc1 폴더 구조.

 

 

두 번째. SenchaCmd 확인.

 

SenchaCmd 설치가 잘 되었는지 확인을 해 보자. 터미널에서 방금 압축 해제 하고 폴더를 복사한 곳으로 이동을 한다. 그곳에서 <그림 5>와 같이 간단하게 sencha 명령어를 테스트 해 보자. <그림 5>와 같이 나타나면 모든 것이 정상으로 끝이 난 것이다.

 

<그림 5> sencha 명령어 테스트.

 

 

세 번째. 프로젝트 생성 및 웹 브라우저 테스트 확인.

 

실제 프로젝트를 하나 생성 하자. <그림 6>과 같이 sencha generate app Test ../Test라고 입력을 해 보자. <그림 6>과 같이 결과가 보일 것이다.

 

<그림 6> sencha generate app Test ../Test

 

이제는 크롬이나 사파리에서 생성된 프로젝트를 실행하여 보자. 실제 url 주소는 각자 다를 것이다. 본인의 url 주소는 http://localhost/~yaioyaio/SenchaProject.2.1-RC1/Test/ 와 같다. <그림 7>과 같이 나오면 모든 것이 정상으로 된 것이다.

 

 

<그림 7> 웹 브라우저 테스트.

 

마지막으로 당부를 하나 하자면 이 번 테스트는 아직 정식 버전이 아닌 것이므로 변화가 있다는 것을 확인 하는 것으로 만족해야 한다는 것이다. 다만, 몇 가지 확인해본 결과 정식 버전이 빨리 나오기를 기다릴뿐이다.

Sencha Touch 2.0 vs Sencha Touch 2.1 beta3의 List와 DataView의 분석.


네이버카페 : http://cafe.naver.com/mobilewebapp/2896

Sencha Touch 2.0 vs Sencha Touch 2.1 beta3의  List와 DataView의 분석.


센차 터치라는 것으로 웹앱을 개발 하면서 가장 많이 부담을 느끼는 부분이 리스트와 UI 부분이다. 기존 Sencha Touch 2.0.x 버전의 List 경우는 사용자의 터치 스크롤 감도를 떨어뜨려 사용성의 불만을 표시 하고 있으며, 이런 속도 문제가 UI 부분에도 많은 영향을 미치는 것을 알고 있다. 앱을 사용 하는 사용자도 만족스럽지 못하다고 이야기한다. 그래서 센차 터치를 이용한 하이브리드 앱을 개발하는데 있어 망설여지고, 다시 네이티브 앱 개발로 돌아 가는 경우도 심심치 않게 보이는 것 같다. 그런데 이 번에 Sencha 사에서 새로운 테스트 버전인 Sencha Touch 2.1 beta3 버전을 내 놓았고, 그 내용이 Sencha 홈 페이지의 포럼을 통하여 알려 지게 되었다. 그 새로운 버전에서 가장 심각한 부분인 List가 새롭게 변경 되었다고 한다.

이 번 문서의 내용은 새롭게 변경된 스크롤 부분의 내용을 가지고 이전 버전과 같이 테스트를 하면서 변화된 모습을 보고 싶다. 이 번 테스트는 전문적인 지식을 바탕으로 “이것이 정답이다”라고 입증 하고 판단 하는 것 보다는, 일반적인 상황에서 단순한 테스트를 통하여 실제 육안으로 보고 버전 차이가 어떤 것인지 그리고 어떤 내용이 추가 되었는지 확인 하면서 설명을 할 것이다. 그러므로 내용 중 실제 사실과 다른 것이 있다면 필자 및 모든 개발자와 공유 하기를 바라고, 더 발전 시켜 나가기를 바라는 마음에서 베포 하고자 한다. 이렇게 하게 된 이유는 https://gist.github.com/3739543 사이트의 내용을 보면서 힌트를 얻었고 테스트 해 보고자 하는 생각이 들었기 때문이다.

※ 비교 목적.
Sencha Touch 2.1 beta3 버전을 통해 테스트 하면서 개발 과정에서 부딪히는 속도 문제의 개선 가능 여부를 단순하게 비교 및 평가하고, 가장 큰 변화가 있는 List 구현 방법의 정체를 확실하게 이해를 돕기 위한 것이다. 그리고 센차 터치로 개발하는 모든 분들에게 다시금 희망을 가질 수 있는 계기가 되었으면 하는 바램도 있다.

※ 비교 대상.
Sencha Touch 2.0.x.x  vs  Sencha Touch 2.1 beta3의 Ext.List와 Ext.DataView의 xtype에 종류에 따라 List가 어떻게 생성 되고, 어떻게 작동 하는지 비교 한다.

※ 비교 방법.
2가지 프로젝트를 생성 하여 실제 생성되는 리스트와 스크롤 시 변화 되는 모습을 파악 한다. 프로젝트는 다음과 같이 2가지 방법으로 구성을 할 것이다.

  1. Sencha Touch 2.0.1.1 Framework과 Sencha SDK Tools 2.0.0 beta3를 이용하여 생성한 ListDataView 프로젝트 테스트.
  2. Sencha Touch 2.1 Framework beta3와 Sencha Cmd 3.0.0 beta를 이용하여 생성한 DataViewDataItemListItem 프로젝트 테스트.

※ 프로젝트 생성 및 테스트.

첫 번째 ListDataView 프로젝트.

– Sencha Touch 2.0.1.1 Framework을 이용한 프로젝트 진행.


Sencha Touch 2.0.1.1 Framework과 Sencha SDK Tools 2.0.0 beta3를 이용 하여 ListDataView 라는 프로젝트를 생성 한다. 프로젝트를 생성 하는 과정은 많은 곳에 나와 있으므로 별도로 설명을 하지 않겠다.

ListDataView 프로젝트 안에 우리가 테스트 할 몇 가지 클래스를 정의 하고 사용할 것이다. 크롬의 요소 검사를 통하여 정의된 클래스 종류에 따라 DOM 객체에 생성되는 리스트(<div>)가 어떻게 그리는지 확인 할 것이며, 스크롤 시 리스트가 어떻게 동작 하는지도 함께 확인 할 것이다.

ListDataView 프로젝트에서 사용 하는 클래스는 다음과 같이 4가지를 확장해서 사용할 것이다.

㉠ extend: ‘Ext.List’

㉡ extend: ‘Ext.dataview.List’

㉢ extend: ‘Ext.DataView’

㉣ extend : ‘Ext.dataview.component.DataItem’.

   Ext.dataview.component.DataItem을 확장한 클래스의 뷰는 다음과 같이 구성을 하였다.

               xtype         : ‘dataview’,
useComponents : true,
defaultType   : ‘mydataitem’,

본격적으로 ListDataView 프로젝트를 생성하자. ListDataView 프로젝트 생성 명령은 다음과 같다.

e:\WebServer\SenchaProject\sencha-touch-2.0.1.1-commercial>c:\SenchaSDKTools-2.0.0-beta3\sencha app create ListDataView ../ListDataView

sencha 명령어를 위와 같이 한 이유는 필자의 PC에 Sencha SDK Tools와 Secnah Cmd가 동시에 설치 되어 있기 때문에 단순히 sencha 명령어만 하게 되면 에러가 발생한다. 그래서 위와 같이 sencha 명령어 파일이 위치한 곳을 지정하고 sencha 명령어를 실행 한 것이다.

생성된 프로젝트에서 다른 파일은 수정을 하지 말고 app.js 파일만 다음과 같이 수정 한다.

app.js 소스

//<debug>

Ext.Loader.setPath({

  ‘Ext’: ‘sdk/src’

});

//</debug>

Ext.define(‘MyList’, {

  extend: ‘Ext.List’,

  xtype  : ‘mylist’,

  config : {

      itemTpl: ‘{test}’

  }

});

Ext.define(‘MyDataViewList’, {

  extend: ‘Ext.dataview.List’,

  xtype  : ‘mydataviewlist’,

  config : {

      itemTpl: ‘{test}’

  }

});

Ext.define(‘MyDataView’, {

  extend: ‘Ext.DataView’,

  xtype  : ‘mydataview’,

  config : {

      itemTpl: ‘{test}’

  }

});

Ext.define(‘MyDataItem’, {

  extend : ‘Ext.dataview.component.DataItem’,

  xtype  : ‘mydataitem’,

  config : {

      dataMap : {

          getTest : { setHtml : ‘test’ }

      },

      test   : {flex : 1},

  },

  applyTest : function (config) {

      return Ext.factory(config, Ext.Component, this.getTest());

  },

  updateTest : function (test) {

      if (test) { this.add(test); }

  }

});

Ext.application({

  name: ‘ListDataView’,

  requires: [

      ‘Ext.dataview.List’,

      ‘Ext.data.Store’,

      ‘Ext.layout.HBox’

  ],

  viewport : {

      layout   : {

          type  : ‘hbox’,

          align : ‘stretch’

      },

      defaults : {

          flex  : 1

      }

  },

  launch: function() {

      // Destroy the #appLoadingIndicator element

      Ext.fly(‘appLoadingIndicator’).destroy();

      // Initialize the main view

      Ext.Viewport.add([

          {

              xtype : ‘mylist’,

              style : ‘background-color: yellow’,

              store : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext List 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          },{

              xtype : ‘mydataviewlist’,

              store : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext dataview List 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          },{

              xtype : ‘mydataview’,

              style : ‘background-color: cyan’,

              store : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext DataView 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          },{

              xtype         : ‘dataview’,

              style         : ‘background-color: white’,

              useComponents : true,

              defaultType   : ‘mydataitem’,

              store         : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext dataview component DataItem 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          }

      ]);

  }

});


<소스 1> ListDataView 프로젝트 소스.

위의 <소스 1>은 짧게 하느라 인라인 데이터를 5개만 했다. 실제 코딩 작업 하는 여러분은 100개씩 만들어 테스트를 하도록 합시다. 모든 코딩이 완료되면 저장하고, 일단 실행부터 시켜보자 <그림 1>과 같이 실행 화면이 보일 것이다.

<그림 1> ListDataView 프로젝트 실행 화면.

자, 이제부터 코딩된 소스를 크롬에서 돌려 보고 어떤 내용들이 있는지 확인 하는 과정을 밟아 보도록 한다. <그림 1>과 같이 나온 상태에서 첫 번째 리스트에서 마우스 오른쪽 버튼을 클릭 하여 요소 검사를 실행한다. 첫 번째 리스트의 요소 검사 결과는 <그림 2>와 같다.



<그림 2> 첫 번째 Ext.List 뷰의 요소 검사 내용.

<그림 2>를 보면 전체 내용이 캡쳐 되지는 않았다. 일부러 짧게 캡쳐를 한 것이다. 실제 100개의 <div>가 보일 것이다. sencha touch 2.0.x.x 버전으로 생성된 프로젝트의 리스트는 연결된 데이터의 개수 만큼 <div>를 모두 DOM에 그리는 것을 볼 수 있다. 나머지 3개의 모든 리스트 요소 검사를 해 보라. 똑 같은 상황이 나타날 것이다.

다음은 스크롤 시 어떻게 <div>의 움직임이 있는 지를 확인해 보도록 한다. 우선 <그림 3>을 보자. <div>의 -webkit-transform: translate3d(0px, 0px, 0px); 좌표 값이 0px, 0px, 0px으로 되어 있다.



<그림 3> 첫 실행 시 <div>의 -webkit-transform: translate3d(0px, 0px, 0px); 좌표 값.

마우스로 리스트를 아래로 움직이면서 요소 검사의 -webkit-transform: translate3d 좌표 값을 유심히 봐 두도록 한다. <그림 4>와 같이 가운데 부분의 좌표 값이 마이너스와 플러스로 변경 되는 것을 볼 수 있다. 결국 큰 <div>를 -webkit-transform: translate3d 이것을 이용하여 전체를 움직이고 있다는 것을 볼 수 있다. 엄청난 일을 하고 있는 것이다. 화면이 작아서 안 보이는 것처럼 생각이 되고 속도의 저하가 없을 것이라 판단이 될 수 있지만, 사실은 그렇지 않은것 같다. HTML DOM에는 많은 <div>를 생성하고 진행 하는 것을 확인 하게 되었다.



<그림 4> 마우스로 리스트를 스크롤 시 <div>의 -webkit-transform: translate3d(0px, -566px, 0px); 좌표 값.

요소 검사 화면에서 -webkit-transform: translate3d(0px, -566px, 0px); 이 부분을 마우스로 더블 클릭 하여 직접 가운데 좌표 값을 변경해 보자. 변경 하고 엔터를 치면 화면에서 리스트가 움직이는 것을 볼 수 있다.

그리고 <그림 5>를 보면 화살표로 안내 하는 화면의 내용을 보면 class=”x-inner x-list-inner x-scroll-scroller”의 크기 값이 픽셀로 표시 되어 있다. 100개의 리스트를 만들기 위한 전체 가로 * 세로 크기를 우리는 알 수 있다.



<그림 5> x-inner x-list-inner x-scroll-scroller 가로 * 세로 픽셀 크기.

결국, 많은 내용의 데이터를 리스트에 뿌리기 위해서는 그 만큼의 <div>를 만들어 놓고 시작한다는 것이다. 이곳에서 일반적인 리스트와 같이 이미지와 구조화 된 내용을 보여 주고 있지 않지만, 이런 단순한 상황도 웹 브라우저를 사용하는 모바일 상황에서는 엄청난 부담이 되는 사실일 것이다. 또한 이런 리스트 뷰가 많을 수록 앱의 전체 속도는 더욱 나빠질 것이고, 앱을 사용 하는 고객 대부분은 스크롤과 메뉴 이동 시 부드럽지 못한 경험을 하게 될 것이다. 단순한 뷰를 만들어 사용 하는 것이 아니라면 많은 사용자들이 앱 사용을 꺼리게 될 것이다.

두 번째 DataViewDataItemListItem 프로젝트.

– Sencha Touch 2.1 Framework beta3를 이용한 프로젝트 진행.


Sencha Touch 2.1 Framework beta3와 Sencha Cmd 3.0.0 beta를 이용 하여 DataViewDataItemListItem 라는 프로젝트를 생성 한다. 프로젝트를 생성 하는 방법은 이전 버전과 크게 다르지 않다. 이것을 테스트 하기 위해서는 2가지를 다운 받아 압축을 해제 하고 설치 하는 과정을 거쳐야 한다. 설치 과정은 이곳에서 설명을 하지 않기로 한다.  다운 받는 곳만 알려 주도록 한다.

Sencha Touch 2.1 beta3 와 Sencha Cmd 3.0 beta 다운로드 : http://www.sencha.com/forum/announcement.php?f=89

DataViewDataItemListItem 프로젝트 안에 우리가 테스트 할 5 가지 클래스를 정의 하고 사용할 것이다. 물론 실행 하면서 테스트 하는 과정은 첫 프로젝트와 다를 것이 없다. 그때와 똑 같이 리스트 생성 방법과 스크롤 시 어떠한 변화가 있는지 확인할 것이다.

두 번째 DataViewDataItemListItem 프로젝트에서 사용할 클래스는 다음과 같이 5가지를 확장해서 구성했다.

㉠ extend: ‘Ext.List’

㉡ extend: ‘Ext.dataview.List’

㉢ extend: ‘Ext.DataView’

㉣ extend : ‘Ext.dataview.component.DataItem’

   Ext.dataview.component.DataItem을 확장한 클래스 뷰는 다음과 같이 구성을 하였다.

xtype : ‘dataview’

               useComponents : true,
defaultType : ‘mydataitem’,

㉤ extend : ‘Ext.dataview.component.ListItem’

   Ext.dataview.component.ListItem을 확장한 클래스 뷰는 다음과 같이 구성을 하였다.

               xtype : ‘list’,
useComponents : true,
defaultType : ‘mylistitem’,

DataViewDataItemListItem 프로젝트 생성 명령은 다음과 같다.

E:\WebServer\SenchaProject2.1\sencha-touch-2.1.0-beta3> sencha generate app DataViewDataItemListItem ../DataViewDataItemListItem

DataViewDataItemListItem 프로젝트를 생성 하고 난 이후 다른 파일은 수정할 필요가 없고, app.js 파일만 다음과 같이 수정한다.

소스 내용.

//<debug>

Ext.Loader.setPath({

  ‘Ext’: ‘touch/src’,

  ‘DataViewDataItemListItem’: ‘app’

});

//</debug>

Ext.define(‘MyList’, {

  extend: ‘Ext.List’,

  xtype  : ‘mylist’,

  config : {

      itemTpl: ‘{test}’

  }

});

Ext.define(‘MyDataViewList’, {

  extend: ‘Ext.dataview.List’,

  xtype  : ‘mydataviewlist’,

  config : {

      itemTpl: ‘{test}’

  }

});

Ext.define(‘MyDataView’, {

  extend: ‘Ext.DataView’,

  xtype  : ‘mydataview’,

  config : {

      itemTpl: ‘{test}’

  }

});

Ext.define(‘MyDataItem’, {

  extend : ‘Ext.dataview.component.DataItem’,

  xtype  : ‘mydataitem’,

  config : {

      dataMap : {

          getTest : { setHtml : ‘test’ }

      },

      test   : { flex : 1 },

  },

  applyTest : function (config) {

      return Ext.factory(config, Ext.Component, this.getTest());

  },

  updateTest : function (test) {

      if (test) { this.add(test); }

  },

});

Ext.define(‘MyListItem’, {

  extend : ‘Ext.dataview.component.ListItem’,

  xtype  : ‘mylistitem’,

  config : {

      dataMap : {

          getTest : {setHtml : ‘test’}

      },

      test   : {flex : 1},

  },

  applyTest : function (config) {

      return Ext.factory(config, Ext.Component, this.getTest());

  },

  updateTest : function (test) {

      if (test) { this.add(test); }

  },

});

Ext.application({

  name: ‘DataViewDataItemListItem’,

  requires: [

      ‘Ext.MessageBox’,

      ‘Ext.dataview.List’,

      ‘Ext.data.Store’,

      ‘Ext.layout.HBox’

  ],

  viewport : {

      layout   : {

          type  : ‘hbox’,

          align : ‘stretch’

      },

      defaults : {

          flex  : 1

      }

  },

  launch: function() {

      // Destroy the #appLoadingIndicator element

      Ext.fly(‘appLoadingIndicator’).destroy();

      // Initialize the main view

      Ext.Viewport.add([

          {

              xtype : ‘mylist’,

              style : ‘background-color: yellow’,

              flex  : 1,

              store : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext List 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          },

          {

              xtype : ‘mydataviewlist’,

              flex  : 1,

              store : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext dataview List 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          },

          {

              xtype : ‘mydataview’,

              flex  : 1,

              style : ‘background-color: cyan’,

              store : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext DataView 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          },

          {

              xtype         : ‘dataview’,

              flex          : 2,

              useComponents : true,

              defaultType   : ‘mydataitem’,

              store         : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext dataview component DataItem 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          },

          {

              xtype         : ‘list’,

              flex          : 2,

              style         : ‘background-color: white’,

              useComponents : true,

              defaultType   : ‘mylistitem’,

              store         : {

                  fields : [‘test’],

                  data   : [

                      { test : ‘Ext dataview component ListItem 1’   },

                      { test : ‘2’   },

                      { test : ‘3’ },

                      { test : ‘4’   },

                      { test : ‘5’   },

                      { test : ‘6’ },

                      { test : ‘7’   },

                      { test : ‘8’   },

                      { test : ‘9’ },

                      { test : ’10’   },

                  ]

              }

          }

      ]);

  }

});


<소스 2> DataViewDataItemListItem 프로젝트 소스

 



<그림 6> DataViewDataItemListItem 프로젝트 실행 화면.

두 번째 생성한 DataViewDataItemListItem 프로젝트를 분석 하기로 하자. 작성된 코드를 저장 하고 크롬에서 돌려 보도록 한다. <그림 6>과 같이 실행된 내용이 보일 것이다. 첫 번째 프로젝트에서 사용했던 방법과 동일하게 리스트에서 마우스 오른쪽 버튼을 클릭 하여 요소 검사를 실행한다. DataViewDataItemListItem 프로젝트의 첫 번째 리스트의 요소 검사 결과는 <그림 7>과 같다.

자, 여기에서 중요한 것 하나를 확인할 수 있다. EXT.List를 사용하는 경우 인라인 데이터 개수 만큼 리스트가 요소 검사에서 보이는 것이 아니고, 웹 브라우서 화면에 보이는 리스트 개수보다 2개의 <div>가 더 생겼을 뿐이다. 그러니까 화면에서 보이는 리스트 개수가 4개이면 요소 검사에서 보이는 <div>는 총 6개가 생기는 것이다. 첫 ListDataView 프로젝트에서 생성된 <div>의 개수 100개를 생성 하지 않았다는 것이다.  이러한 내용은 sencha touch 2.1 beta3에서 새롭게 변경된 리스트이다. 다음의 url 주소를 보면 나와 있는 내용이다.



<그림 7> 첫 번째 Ext.List 뷰의 요소 검사 내용.

What’s Coming in Sencha Touch 2.1 을 보면 자세하게 <그림 8>과 같이 안내가 되어 있다. 네이티브에서 구현 하는 리스트와 같은 방식으로 리스트를 재 사용 하는 스텍 구조의 형태로 되어 있다는 것이다. 데이터 개수 만큼 리스트를 만들지 않으므로 당연히 가벼워 질 것이며, 동적으로 리스트를 스토어와 바인딩 된다 봐야 할 것이다.

<그림 8> Advanced List component with Infinite scrolling


중요한 사실을 하나 확인을 하였다. 나머지 4개의 리스트보 같은 방법으로 확인을 각자 해 보기를 바란다. 테스트를 하다 보면 List가 들어 가는 클래스를 사용하는 경우는 데이터 만큼의 리스트를 만들지 않고 동적으로 바인딩 하여 사용 하는 스텍 구조의 리스트를 재 사용하는 것을 볼 수 있다.

우선 첫 번째 리스트의 CSS 클래스 내용을 보도록 하자. <그림 9>를 보면, Ext.List를 사용 하는 리스트의  첫 번째 리스트 요소 검사에 대한 내용이다. 새로운 CSS의 클래스가 보일 것이다. “x-list-item-first x-list-header-wrap” 클래스가 추가 되었으며, 첫 번째라는 것을 알 수 있게 “x-list-item-first“이 들어 있다.



<그림 9> Ext.List의 첫 번째 리스트 요소 검사.

<그림 10>를 보면, Ext.List를 사용 하는 리스트의  마지막 리스트 요소 검사에 대한 내용이다. 새로운 CSS의 클래스가 보일 것이다. “x-list-item-last x-list-footer-wrap” 클래스가 추가 되었으며, 첫 번째라는 것을 알 수 있게 “x-list-item-last“이 들어 있다.



<그림 10> Ext.List의 마지막 리스트 요소 검사.

이 번에는 리스트를 스크롤 하여 어떻게 변경 되는지 확인을 해 보자. <그림 11>를 보자. Ext.List를 사용 하는 리스트의  경우 스크롤 하면 각각의 리스트에 있는 CSS 스타일 속성 중 하나인  -webkit-transform: translate3d(0px, 157px, 0px)의 가운데 좌표 값이 변경 되는 것을 육안으로 확인 가능하다. DOM에 그려진 <div> 리스트 전체의 -webkit-transform: translate3d 좌표 값을 변경 하는 것이다. 첫 번째 ListDataView 프로젝트에서는 100개의 <div>를 가지고 있는 <div>가 좌표 값을 변경 하는 것을 봤다. sencha touch 2.1 beta3에서는 그렇게 작동 하지 않는 다는 것을 이번 테스트를 통해 확인을 하였다.



<그림 11> 리스트를 스크롤 시 변화되는 -webkit-transform: translate3d 좌표 값.

리스트의 전체 크기를 첫 프로잭트에서 확인을 하였다. 두 번째 프로젝트에서 리스트 전체 크기는 <그림 12>와 같다. 당연히 세로 크기가 엄청나게 많이 줄어 들었다.



<그림 12> DataViewDataItemListItem 프로젝트 첫 번째 리스트 세로 크기.

마지막으로 한 가지를 더 확인해 보도록 하자. 기존 버전에서 제공 하는 Ext.dataview.component.DataItem 클래스가 있지만, sencha touch 2.1 beta3에서는 Ext.dataview.component.ListItem 클래스가 하나 추가 되었다. 사용자 정의 리스트를 만들어 사용 하는데, Ext.List와 같은 역활의 리스트를 구현 하는  Ext.dataview.component.ListItem 클래스이다. 마지막 리스트까지 확인을 해 보았다면 무엇을 의미 하는지 알 수 있을 것이다.

 

세 번째 결론 및 맺음말.

결론을 말씀 드리자면, 센차사의 사이트내 포럼을 통해 새롭게 공개한 sencha touch 2.1 beta3 버전은 큰 일을 한 것으로 판단이 된다. 오픈 소스를 제공하는 회사에서 많은 개발자의 불만을 크게 반영한 것이라 볼 수 있다. 리스트와 스크롤 방식이 기존 네이티브에서 제공 하는 리스트 재 사용을 할 수 있도록 스텍 구조로 변경이 되었다는 것이 너무 반가운 소식이다. 모바일에서 테스트를 하지는 못 했지만, 여태 테스트 한 내용을 기반으로 본다면 당연히 새로운 버전의 리스트 속도가 훨씬 빠를 것이며, 전체 앱의 속도에도 많은 변화가 있을 것으로 판단이 된다. 또한, 새롭게 추가된 Ext.dataview.component.ListItem 클래스가 있다는 것을 알 수 있다.

참고 사이트.
http://www.sencha.com/forum/announcement.php?f=89
http://dev.sencha.com/deploy/sencha-touch-2.1.0-b3/release-notes.html
http://www.sencha.com/blog/whats-coming-in-sencha-touch-2-1?mkt_tok=3RkMMJWWfF9wsRokuazPZKXonjHpfsX87O8pUKazlMI%2F0ER3fOvrPUfGjI4ESsN0dvycMRAVFZl5nR9dFOOdfQ%3D%3D
https://gist.github.com/3739543

 

Zen Coding(젠 코딩)을 이클립스에서 사용 하는 방법. – 2


네이버 카페 : http://cafe.naver.com/mobilewebapp/1004

이클립스에서 Zen Coding을 타이핑 하고 맥에서 “Command 키 + E”, 윈도우에서 “Alt + E” 라고 하면 자동으로 해당 하는 html, css, xml등 관련하여 자동으로 코딩을 변환 하여 준다.

이제부터는 약간의 젠 코딩에 대한 맛을 개발자분들께서 느낄 수 있도록 직접 테스트를 해 볼 차례이다.

이클립스에서 빈 html 파일을 하나 생성 하자. html 파일을 실행을 하는 것이 아니고 젠 코딩(Zen Coding)으로서 html 소스를 변환 하는 과정이 얼마나 편리한지 또 얼마나 빠르게 코딩이 가능한지 알아 보고자 하는 시간이다.

빈 html 파일을 만들었으면 다음과 같이 코딩을 하고 위에 적어 놓은 단축키를 눌러 보자.

Zen Coding 테스트 1. – html5 관련 기본 문서를 만드는 과정이다.

html:5

변환 결과 코드.

<!DOCTYPE HTML>

<html lang=”en-US”>

<head>

<meta charset=”UTF-8″>

<title></title>

</head>

<body>

</body>

</html>

Zen Coding 테스트 2.- id 생성.

div#name

변환 결과 코드.

<div id=”name”></div>

Zen Coding 테스트 3. – class 생성

div.name

변환 결과 코드.

<div></div>

Zen Coding 테스트 4. – 1개 이상 class 생성

div.one.two

변환 결과 코드.

<div></div>

Zen Coding 테스트 5. – 1개 id와 1개 이상 class 생성

div#name.one.two

변환 결과 코드.

<div id=”name”></div>

Zen Coding 테스트 6. – 1개 id와 1개 이상 class 생성

div#name.one.two

변환 결과 코드.

<div id=”name”></div>

Zen Coding 테스트 7. – 부모 Element 와 자식 Element

head>link

변환 결과 코드.

<head>

<link rel=”stylesheet” href=”” />

</head>

Zen Coding 테스트 8. – 부모 Element 와 자식 Element Table 생성

table>tr>td

변환 결과 코드.

<table>

<tr>

<td></td>

</tr>

</table>

Zen Coding 테스트 9. – 부모 Element ID 생성과 자식 Element Class 생성

ul#name>li.item

변환 결과 코드.

<ul id=”name”>

<li></li>

</ul>

Zen Coding 테스트 10. – Element 와 Element 를 더해서 생성.

p+p

변환 결과 코드.

<p></p>

<p></p>

Zen Coding 테스트 11. – 1개 ID를 가진 부모 Element 와 2개의 같은 자식 Element인데 다른 Class.

div#name>p.one+p.two

변환 결과 코드.

<div id=”name”>

<p></p>

<p></p>

</div>

Zen Coding 테스트 12. – Element Attributes 속성.

div[title]

a[title=”Hello world” rel]

td[colspan=2]

변환 결과 코드.

<div title=””></div>

<a href=”” title=”Hello world” rel=””></a>

<td colspan=”2″></td>

Zen Coding 테스트 13. – Multi Element 생성.

p*3

변환 결과 코드.

<p></p>

<p></p>

<p></p>

select>option#item-$*3

변환 결과 코드.

<select name=”” id=””>

<option value=”” id=”item-1″></option>

<option value=”” id=”item-2″></option>

<option value=”” id=”item-3″></option>

</select>

Zen Coding 테스트 14. – Multi Element 생성.

ul#name>li.item*3

변환 결과 코드.

<ul id=”name”>

<li></li>

<li></li>

<li></li>

</ul>

Zen Coding 테스트 15. – Multi Element 자동 숫자 증가.

ul#name>li.item$*3

변환 결과 코드.

<ul id=”name”>

<li></li>

<li></li>

<li></li>

</ul>

Zen Coding 테스트 16. – Multi Element 자동 숫자 증가.(자릿수 지정).

ul#name>li.item$$$*12

변환 결과 코드.

<ul id=”name”>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

</ul>

Zen Coding 테스트 17. – 자식이 있는 부모 Element 자동 생성.

ul+

변환 결과 코드.

<ul>

<li></li>

</ul>

dl+

변환 결과 코드.

<dl>

<dt></dt>

<dd></dd>

</dl>

table+

변환 결과 코드.

<table>

<tr>

<td></td>

</tr>

</table>

Zen Coding 테스트 18.

div#page>div.logo+ul#navigation>li*5>a

변환 결과 코드.

<div id=”page”>

<div></div>

<ul id=”navigation”>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

</ul>

</div>

Zen Coding 테스트 19.

div#page>(div#header>ul#nav>li*4>a)+(div#page>(h1>span)+p*2)

변환 결과 코드.

<div id=”page”>

<div id=”header”>

<ul id=”nav”>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

</ul>

</div>

<div id=”page”>

<h1><span></span></h1>

<p></p>

<p></p>

</div>

</div>

Zen Coding 테스트 20.

div#page>(div#header>ul#nav>li*4>a)+(div#page>(h1>span)+p*2)+div#footer

변환 결과 코드.

<div id=”page”>

<div id=”header”>

<ul id=”nav”>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

</ul>

</div>

<div id=”page”>

<h1><span></span></h1>

<p></p>

<p></p>

</div>

<div id=”footer”></div>

</div>

이상 젠 코딩 관련된 일반적인 사용법에 대하여 테스트까지 완료 하였씁니다.

개발자 여러분께서 사용하는 스타일과 에디터가 많이 다를 수 있지만, 젠 코딩 사이트에 보면 지원 하는 많은 에디터와 서드 파트에서 직접 개발되어 지원 되는 경우가 많으니 각 에디터 개발사 사이트를 방문 하여 직접 확인 하시는 것도 좋을것 같습니다. 국내에서 많이 사용하는 에디터 플러스는 최신 버전을 사용하면 자동으로 내장되어 있어 바로 사용이 가능한 것으로 알고 있다.

또한 http://vimeo.com/7405114 동영상을 보셔도 많은 도움이 될 것입니다.

프로필.
소속: (주)애드웹커뮤니케이션

부서 : 개발팀

직위: 팀장

이름 : 안병도(꼬장)

메일 : yaio@naver.com,
yaioyaio@gmail.com,
program@adweb.co.kr

네이버카페 : http://cafe.naver.com/mobilewebapp

트위터 : @yaioyaio

페이스북 : http://www.facebook.com/byoungdo.ahn
페이스북그룹 : http://www.facebook.com/groups/korea.sencha/

워드프레스: https://yaioyaio.wordpress.com/
티스토리 : http://senchatouch.tistory.com/

Zen Coding(젠 코딩)을 이클립스에서 사용 하는 방법. – 1


Zen Coding(젠 코딩)을 이클립스에서 사용 하는 방법.

네이버 카페 : http://cafe.naver.com/mobilewebapp/1003

ZenCoding 은 html과 CSS를 코딩 하는 과정에서의 불편함을 해소 하고 빠른 코딩을 하고자 출발이 된 것으로 알고 있다.

본인도 어느 컨퍼런스를 갔다 우연히 듣고 몇 번 사용만 하다가 Node.js 및 Jade와 같은 것을 사용 하고자 다시 한번 정리 하는 차원에서 문서를 만들게 되었다.

어디에 쓸모가 있을까 싶지만 CSS와 HTML을 쉽게 다루고자 하는 개발자라면 조금 배워둘 필요도 있다고 판단이 되어 아직 모르고 있거나 알면서 사용이 처음 접하시는 분들을 위해 정보를 공유 하고자 작성하게 된 이유도 있다.

ZenCoding에 대한 자세한 사용법 및 문서와 각종 에디터 프로그램에서 사용이 가능 하도록 제공 하는 사이트는 다음과 같다.

Zen Coding 공식 사이트 :  http://code.google.com/p/zen-coding/

물론 일부 서드 파트의 에디터들은 직접 제공 하는 경우도 있으나, 대부분 플러그인 방식으로 젠 코딩에 대한 것을 많이 제공 하고 있으며, 젠 코딩도 프로그램 개발에 있어 많은 이슈의 하나로 떠 오르고 있는 것도 사실이다.

위의 사이트에 방문 하셔서 여러분들께서 사용 하는 에디터에 맞는 것을 다운 받아 사용하시면 되며, 더 자세한 내용은 각 에디터 개발사의 사이트나 구글링을 하면 많은 정보들이 나와 있다.

대표적으로 많이들 사용하는 에디터 이클립스에 대한 것만 다룰 것이다.

그 이전에 젠 코딩의 문법에 대한 것을 먼저 알아 보고자 한다.

기본적인 문법을 설명 해 보도록 하자.

1. ID or Class 속성에 대한 사용법.
– Element에 id 붙이는 방법은 div#name 이라고 하면 된다.
– Element에 class를 붙이는 방법은 div.name 이라고 하면 된다.
– Element에 id와 class를 같이 사용하는 방법은 div#name.name 이라고 하면 된다.
– Element에 class를 1개 이상 사용하는 방법은 div.name01.name02 라고 하면 돠다.

2. Element에 사용자 속성을 지정 하는 방법은 [ ]를 사용하면 된다.
– div[title]

– a[title=”Hello world” rel]

– td[colspan=2]

3. 여러 개의 Element를 반복 지정 하는 방법은 * 기호를 사용하면 된다.
– <li> 태크를 5개 반복 생성 할때는 li*5 하고 하면 된다.

4. Element에 대한 자동 증가 넘버를 매기는 방법은 $ 기호를 사용하면 된다.

– li.item$*3

5. Element에 대한 자동 증가 넘버를 매기는 방법 중 자리수를 지정 하는 방법은 $ 기호를 갯수 만큼 사용하면 된다.

– li.item$$$*15

6. 여러 개의 Element를 동시에 생성 하는 방법은 + 기호를 사용하면 된다. 또한 + 기호를 html 태그와 붙여서 사용하면 자식으로 속하는 Element까지 자동으로 생성해 준다.
– div#haeder+div#contents+div#footer

– table+

7. 부모 Element에 자식 Element를 생성 하고자 할 때는 > 기호를 사용하면 된다.

– div#header>ul>li

8. 하나로 묶어 주는 그룹 기능은(무한 중첩 포함) ( ) 기호로 묶어서 사용하면 된다.

– div#page>(div#header>ul#nav>li*4>a)

9. 젠 코딩을 사용하여 # 또는 . 을 지정하고 html element를 사용 하지 않으면 기본적으로 div 태그를 생성한다.

– #header.wrap

다음 표는 위의 내용을 간단하게 정리한 표이다.

기호 설명 사용법 결과
. 클래스 생성 div.classname <div class=”classname”></div>
# ID 생성 div#idname <div id=”idname”></div>
[ ] 사용자 속성 생성 div[title] <div title=””></div>
* 반복 생성 li*5 <li></li>

<li></li>

<li></li>

<li></li>

<li></li>

$ 요소를 자동 생성 시,

숫자 증가 값 표시.

li#item$*5 <li id=”item1″></li>

<li id=”item2″></li>

<li id=”item3″></li>

<li id=”item4″></li>

<li id=”item5″></li>

$ li#item$$$*5 <li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

+ 멀티 생성 div#haeder+div#contents+div#footer <div id=”haeder”></div>

<div id=”contents”></div>

<div id=”footer”></div>

+ 자식을 포함 하는 태그 있을 경우 자동 생성 table+ <table>

<tr>

<td></td>

</tr>

</table>

+ dl+ <dl>

<dt></dt>

<dd></dd>

</dl>

> 자식 생성 div#header>ul>li <div id=”header”>

<ul>

<li></li>

</ul>

</div>

( ) 그룹(무한 중첩) div#page>(div#header>ul#nav>li*4>a) <div id=”page”>

<div id=”header”>

<ul id=”nav”>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

<li><a href=””></a></li>

</ul>

</div>

</div>

기타 Element를 지정 하지 않는 경우는 div를 생성한다. #header.wrap <div id=”header”></div>

위의 내용 보다 더 많은 사용법이 있습니다.

다음 주소를 찾아 방문 하시면 Zen Coding cheat sheet 에 대한 2 가지 문서가 있습니다. 다운 받아서 보시고 사용에 대한 테스트를 직접 많이 다루어 보시기를 바랍니다.

http://code.google.com/p/zen-coding/downloads/list

우선 이클립스에서 사용하는 방법을 알아 보도록 합시다.

이클립스에서 Zen Coding 플러그인 설치는 다음 주소를 보셔도 좋습니다.

https://github.com/sergeche/eclipse-zencoding#installation

1. 이클립스를 실행 한다.

2. 이클립스에서 플러그인을 설치 하는 다른 것들과 방법은 똑 같다.
그림과 같이 설치 할 수 있는 곳으로 이동을 해 보자.

플러그인 있는 주소는 http://zen-coding.ru/eclipse/updates/ or http://media.chikuyonok.ru/eclipse/updates 이다.

위와 같이 설치를 완료 하면 이클립스를 재 실행 한다.

그 다음 환경설정.(Preferences)으로 가서 다음과 같이 선택을 하고 저장한다.

다음 시간에는 이클립스에서 직접 테스트를 해 보도록 합시다.

이제 젠 코딩을 사용 하기 위한 이클립스의 모든 설치 및 설정은 끝이 났다.

센차터치(Sench Touch 2) 하단의 탭바(Ext.tab.Panel)와 같이 아이콘 있는 상단 탭바 만들기.(_tabs.scss 및 compass 사용)


센차터치(Sench Touch 2) 하단의 탭바(Ext.tab.Panel)와 같이 아이콘 있는 상단 탭바 만들기.(_tabs.scss 및 compass 사용)

네이버 카페 : http://cafe.naver.com/mobilewebapp

  1. 센차터치의 하단의 탭바를 상단으로 포지션을 변경 하면 아이콘이 없는 상태로 변경이 된다.
    상단의 탭바 상태를 다음과 같이 변경 하고자 한다.그림 1) 과 같은 탭바를 그림 2)와 같은 탭바로 구성 하기 위한 것이 이번 프로젝트 진행의 목적이 있다.

그림 1) 그림 2)
  1. 프로젝트 개발 환경.
    – Mac OSX Lion.
    – sencha touch 2.0.1 framework, sench sdk tools 2.0.0 beta3
    – Sublime Text2.
  2. 프로젝트 생성을 한다.
    프로젝트명은 “TabsTop”으로 한다.
  3. 도스 프롬프트 창이나 맥 OSX 터미널에서 다음과 같이 sencha 명령어로 신규 프로젝트를 생성한다.yaio:sencha-touch-2.0.1-commercial yaioyaio$ sencha app create TabsTop ../TabsTop
  4. 첫 실행 화면은 다음과 같다.
  5. 위의 내용에서 하단의 탭바를 상단으로 똑 같이 나타나게 scss 파일을 수정 작업을 진행할 것이다.다음 차례부터는 _tabs.scss 파일을 수정 하고, app.scss 파일에 한 줄만 추가 하면 하단 탭바를 상단으로 옮기고 같은 형태를 유지 할 수 있다.

    본격적으로 코딩을 해 보도록 합시다.

  6. _tabs.scss 내용 수정한다. – $include-top-tabs-user 변수를 추가.상단에 $include-top-tabs-user 변수를 추가 선언한다.

/*** @var {boolean} $include-top-tabs

* Optionally exclude top tab styles by setting to false.

*/

$include-top-tabs: true !default;

/**

* @var {boolean} $include-bottom-tabs

* Optionally exclude bottom tab styles by setting to false.

*/

$include-bottom-tabs: true !default;

/**

* @var {boolean} $include-top-tabs-user

* Optionally exclude top tab styles by setting to false.

*/

$include-top-tabs-user: true !default;

  1. _tabs.scss 내용 수정한다. – $tabs-top-icon-size 변수를 추가.상단 탭바에 사용할 아이콘 사이즈 $tabs-top-icon-size 변수를 추가 선언 한다.

/*** @var {string} $tabs-bottom-radius

* Border-radius for bottom tabs.

*/

$tabs-bottom-radius: .25em !default;

/**

* @var {string} $tabs-top-icon-size

* Icon size for bottom tabs

*/

$tabs-top-icon-size: 1.65em !default;

/**

* @var {string} $tabs-bottom-icon-size

* Icon size for bottom tabs

*/

$tabs-bottom-icon-size: 1.65em !default;

  1. _tabs.scss 내용 수정한다. – 상단 탭바을 위한 전용 mixin을 추가@mixin sencha-tabs { } 이 부분에 상단 탭바을 위한 전용 mixin을 추가 정의 한다.
    다음과 같이 2군데를 추가 하면 된다.

  @if $include-top-tabs {@include sencha-top-tabs;

}

@if $include-bottom-tabs {

@include sencha-bottom-tabs;

}

// $include-top-tabs-user 이것이 true 이면 sencha-top-tabs-user mixin을 사용

@if $include-top-tabs-user {

@include sencha-top-tabs-user;

}

// sencha-top-tabs-user mixin 정의.
@mixin sencha-top-tabs-user {

.x-tabbar.x-docked-top {

border-top-width: .1em;

border-top-style: solid;

height: 3em;

padding: 0;

.x-tab {

@if $include-border-radius { @include border-radius($tabs-bottom-radius); }

min-width: 3.3em;

position: relative;

padding-top: .2em;

.x-button-icon {

-webkit-mask-size: $tabs-top-icon-size;

width: $tabs-top-icon-size;

height: $tabs-top-icon-size;

display: block;

margin: 0 auto;

position: relative;

}

.x-button-label {

margin: 0;

padding: .1em 0 .2em 0;

font-size: 9px;

line-height: 12px;

text-rendering: optimizeLegibility;

-webkit-font-smoothing: antialiased;

}

}

}

@if $include-default-icons {

@include pictos-iconmask(‘bookmarks’);

@include pictos-iconmask(‘download’);

@include pictos-iconmask(‘favorites’);

@include pictos-iconmask(‘info’);

@include pictos-iconmask(‘more’);

@include pictos-iconmask(‘time’);

@include pictos-iconmask(‘user’);

@include pictos-iconmask(‘team’);

}

}

  1. _tabs.scss 내용 수정한다. – @mixin sencha-tabbar-ui() mixin 수정.다음은 @mixin sencha-tabbar-ui() mixin 내부 맨 끝에 다음 항목을 추가할 차례이다.

  @if $include-top-tabs-user {.x-tabbar-#{$ui-label}.x-docked-top {

.x-inner.x-tabbar-inner.x-layout-hbox { // 탭바의 아이콘이 중앙으로 오도록 설정.

-webkit-box-pack: center !important;

}

.x-tab {

@include bevel-by-background($bar-color);

.x-button-icon {

@include mask-by-background($bar-color, 20%, $tabs-bar-gradient);

}

}

.x-tab-active {

@include background-gradient(darken($bar-color, 5%), recessed);

@include bevel-by-background(lighten($bar-color, 10%));

@if ($include-tab-highlights) {

@include box-shadow(darken($bar-color, 10%) 0 0 .25em inset);

}

.x-button-icon {

@include background-gradient($tab-active-color, $tabs-bottom-active-gradient);

}

}

}

}

  1. 이제는 실제 사용 하고 있는 app.scss 파일에 다음과 같이 한 줄만 첫 줄에 추가 하면 된다.$include-top-tabs: false;
  2. 마지막으로 compass로 scss 파일을 compile 하면 된다.
    – 터미널이나 도스 창에서 해당 프로젝트의 resources/sass 로 이동한다.
    – compass watch 하면 자동으로 scss 파일을 컴파일 하여 실제 사용 하는 app.css 파일을 생성해 준다.
  3. 다음은 실제 실행한 화면의 모습이다.지금 보는 화면은 상단에 그대로 탭바와 툴바가 같이 위치 하는 모습이다.

    지금 보는 화면은 상단에 탭바 하단에 툴바가 위치한 모습이다.

  4. 위의 내용을 다른 방법으로 만들어 좀더 세밀하게 할 수 있을 것이다.

프로필.
소속: (주)애드웹커뮤니케이션

부서 : 개발팀

직위: 팀장

이름 : 안병도(꼬장)

메일 : yaio@naver.com,
yaioyaio@gmail.com,
program@adweb.co.kr

네이버카페 : http://cafe.naver.com/mobilewebapp

트위터 : @yaioyaio

페이스북 : http://www.facebook.com/byoungdo.ahn
페이스북그룹 : http://www.facebook.com/groups/korea.sencha/

워드프레스: https://yaioyaio.wordpress.com/
티스토리 : http://senchatouch.tistory.com/

PhoneGap-1.7.0(Cordova) Eclipse Helios Mac용 Android Tutorial 기본 사용법


PhoneGap-1.7.0(Cordova) Eclipse Helios Mac용 Android Tutorial 기본 사용법

네이버카페 : http://cafe.naver.com/mobilewebapp/532

  1. phonegap-1.7.0(Cordova)을 사용 하기 위한 요구 사항.
    – 이클립스 3.4 이상 버전.(Helios, Indigo)
  2. Install SDK + PhoneGap-1.7.0(Cordova)
    – Eclipse Classic.
    http://www.eclipse.org/downloads/
    : 다운로드 및 설치.(설치는 압축을 해제 하는 것으로 끝난다.)- Android SDK.
    http://developer.android.com/sdk/index.html
    : 다운로드 및 설치.- ADT Plugin.
    http://developer.android.com/sdk/eclipse-adt.html#installing
    : 다운로드 및 설치.- PhoneGap-1.7.0(Cordova)
    http://phonegap.com/download
    : 위의 주소에서 phonegap 관련 자료를 다운로드 받자.
    다음 이미지와 같이 다운로드 폴더에 있을 겁니다. 다운로드 받은 파일의 압축을 해제 한다.

    : 압축을 해제한 다음 폴더의 내용을 계속해서 사용을 할 것이니 잘 정리해서 보관해 두자. 다음과 같은 형태의 폴더 구조를 볼 수 있다.

  3. PhoneGap-1.7.0(Cordova) New Project.- 위의 4가지 사항은 별도로 구글링을 하면 아주 자세히 나와 있다. 조금 시간이 걸리는 작업 이지만 천천히 인내를 가지고 작업해 보시기를 바랍니다.- 이클립스를 실행하자.
    – New > Android Proejct를 클릭 한다.
    – 다음 그림과 같이 프로젝트명등 필요한 정보를 입력 하자.
    : 프로젝트명을 HelloCordova 로 입력 한다.
    : Create new project in workspace 를 체크 한다.
    : use default location 도 같이 체크 한다.
    : 하단의 Next 버튼을 클릭 한다.

    – 다음 이미지에서 보이는 것처럼 최신 안드로이드 버전인 Android 4.0.3 을 체크 한다. 그리고 Next 버튼을 클릭 하고 다음으로 넘어 간다.

    – 다음 이미지와 같이 내용을 입력 및 수정 한다.
    : Application Name – HelloCordova 를 입력한다.
    : Package Name – com.yaio.Hello 를 입력한다.
    : Create Activity 를 체크 한다. 이름은 그대로 사용한다.
    : Minimum SDK 15로 그대로 사용한다.
    : Finish 버튼을 클릭 하여 셋팅을 마무리 한다.

    – 이제 기본적으로 프로젝트의 셋팅을 완료 하였다. 다음 차례는 실제 작업에 필요한 정보를 정리할 단계이다.

  4. 프로젝트에 필요한 PhoneGap-1.7.0(Cordova) 셋팅.
    – 이 단계에서는 앞으로 코딩을 하고 앱으로 제작하기 위한 기본적인 작업을 할 차례이다.
    – 위에서 생성한 프로젝트에 2가지 폴더를 생성할 것이다.
    : /libs,  /assets/www
    – 다음 그림과 같이 프로젝트를 선택 하고 마우스 오른쪽 버튼을 클릭하여 찾아 간다.– 하단의 Floder name 이라는 빈 칸에 “libs”라고 입력 하고 Finish를 클릭한다.
    – 이 번에는 “/assets/www” 폴더를 생성할 것이다. 위와 같은 방법으로 폴더를 생성한다.
    방법은 다음 이미지와 같이 따라 하면 된다.

    – 폴더명을 다음 이미지와 같이 입력을 하고 Finish를 클릭 하여 완료 한다.


    – 폴더 생성을 완료 하였다. 다음은 생성한 폴더에 phonegap 코딩 작업에 필요한 파일을 옮겨 놓을 차례이다.

    – 방법은 이미지와 같은 방법을 따라 하시면 된다.
    이클립스 프로젝트 화면 상태에서 그대로 진행을 하시면 됩니다.

    – 먼저 다운로드 받아서 옮겨 놓은 Finder를 찾아서 cordova-1.7.0.jar 파일을 프로젝트의 libs 폴더에 마우스로 끌어 옮겨 놓는다.

    – 이 번에는 cordova-1.7.0.js 자바스크립트 파일을 마우스로 끌어서 프로젝트의 assets/www 폴더에 옮겨 놓는다.

    – 마지막으로 다음 그림과 같이 xml 폴더를 프로젝트의 /res 폴더에 옮겨 놓을 차례이다. 그림과 같이 마우스로 끌어서 옮겨 놓는다.


    – 작업에 필요한 파일은 모두 옮겨 놓았다. 개발에 필요한 파일을 옮겨 놓은 전체 구조는 다음 이미지와 같다.

    지금까지 따라한 내용과 일치 하는지 확인을 다시 해 보시고 틀린 곳이 있으면 수정 하시기를 바랍니다.

    – 이 번에는 cordova-1.7.0.jar 파일을 사용 가능하도록 Android Dependencies에 등록을 시킬 차례이다.

    다음 그림처럼 프로젝트를 마우스로 오른쪽 버튼 클릭 한 다음 Build Path를 클릭 한다.


    다음은 Configure Build Path… 를 클릭 한다.

    다음은 해당 하는 탭에서 “Add JARs…” 버튼을 클릭한다.

    다음은 팝업창에서 이전에 작업한 cordova-1.7.0.jar 파일을 찾아서 OK 버튼을 클릭한다.

    지금까지 작업한 결과는 다음 이미지와 같이 보일 것이다.

  5. 프로젝트 코딩 및 앱 실행.
    – 지금까지는 코딩 및 실행을 하기 위한 사전 작업을 마무리 하였다. 이제는 실제 코딩을 간단하게 해 볼 차례이다.- 우선 src/com.yaio.Hello 폴더에 있는 HelloCordovaActivity.java 파이을 열어 보자.
    내용은 다음과 같이 되어 있다.– 위의 내용을 다음과 같이 수정을 할 것이다.

package com.yaio.Hello;import org.apache.cordova.DroidGap;import android.os.Bundle;public class HelloCordovaActivity extends DroidGap {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// setContentView(R.layout.main);

super.loadUrl(“file:///android_asset/www/index.html”);

}

}

– 다음은 안드로이드용 AndroidManifest.xml 파일을 수정할 차례이다.

이 AndroidManifest.xml 파일에는 앱이 실행하는데 필요한 기본적인 정보들이 셋팅 되어 있다.

물론 앱이 실행 되어질때 퍼미션 관련한 내용도 같이 정해 주고, 단말기의 회전 여부에 따라 앱의 화면도 변경 될 것인지를 설정 하는 부분도 있다.

다음 이미지는 AndroidManifest.xml  파일의 기본 소스이다.

위와 같은 내용을 다음과 같이 수정을 할 것이다.

<?xml version=”1.0″ encoding=”utf-8″?><manifest xmlns:android=”http://schemas.android.com/apk/res/android“package=”com.yaio.Hello”android:versionCode=”1″

android:versionName=”1.0″ >

<uses-sdk android:minSdkVersion=”15″ />

<supports-screens

android:largeScreens=”true”

android:normalScreens=”true”

android:smallScreens=”true”

android:resizeable=”true”

android:anyDensity=”true” />

<uses-permission android:name=”android.permission.CAMERA” />

<uses-permission android:name=”android.permission.VIBRATE” />

<uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION” />

<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” />

<uses-permission android:name=”android.permission.ACCESS_LOCATION_EXTRA_COMMANDS” />

<uses-permission android:name=”android.permission.READ_PHONE_STATE” />

<uses-permission android:name=”android.permission.INTERNET” />

<uses-permission android:name=”android.permission.RECEIVE_SMS” />

<uses-permission android:name=”android.permission.RECORD_AUDIO” />

<uses-permission android:name=”android.permission.MODIFY_AUDIO_SETTINGS” />

<uses-permission android:name=”android.permission.READ_CONTACTS” />

<uses-permission android:name=”android.permission.WRITE_CONTACTS” />

<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />

<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />

<uses-permission android:name=”android.permission.GET_ACCOUNTS” />

<uses-permission android:name=”android.permission.BROADCAST_STICKY” />

<application

android:icon=”@drawable/ic_launcher”

android:label=”@string/app_name” >

<activity

android:name=”.HelloCordovaActivity”

android:label=”@string/app_name”

android:configChanges=”orientation|keyboardHidden” >

<intent-filter>

<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />

</intent-filter>

</activity>

</application>

</manifest>

– 자, 이제는 마지막으로 실행시 보여 줄 /assets/www/ndex.html 파일을 코딩을 할 차례이다.
위에서 폴더를 생성하던 방식과 유사한 방법으로 파일을 생성한다. 그 내용은 다음 이미지와 같이 따라 하시면 됩니다.

다음 이미지와 같이 파일명을 index.html 입력 하고 저장을 한다.


– 이 번에는 위에서 생성한 index.html 파일을 다음과 같이 코딩을 한다.

<!DOCTYPE HTML><html><head><title>Cordova</title>

<script type=”text/javascript” charset=”utf-8″ src=”cordova-1.7.0.js”></script>

</head>

<body>

<h1>Hello World</h1>

</body>

</html>

– 모든 코딩 작업은 이로서 마무리 되었습니다.

다음은 실제 안드로이드 에뮬레이터로 실행을 해 보도록 합시다.

– 다음 이미지는 위에서 같은 방법으로 제작된 실제 앱의 실행 화면이다.

이로써 모든 준비 작업과 첫 프로젝트를 간단하게 실행까지 해 보았습니다.

다음 시간에는 폰갭을 사용하는 가장 큰 이유의 하나인 단말기 관련된 예제를 가지고 만나 뵙도록 하겠습니다.

다음 내용은 Cordova에서 제공 하는 기능들이다.

  1. Accelerometer
  2. Camera
  3. Capture
  4. Compass
  5. Connection
  6. Contacts
  7. Device
  8. Events
  9. File
  10. Geolocation
  11. Media
  12. Notification
  13. Storage

프로필.
소속: (주)애드웹커뮤니케이션

부서 : 개발팀

직위: 팀장

이름 : 안병도(꼬장)

메일 : yaio@naver.com,

yaioyaio@gmail.com,
program@adweb.co.kr

네이버카페 : http://cafe.naver.com/mobilewebapp

트위터 : @yaioyaio

페이스북 : http://www.facebook.com/byoungdo.ahn
페이스북그룹 : http://www.facebook.com/groups/korea.sencha/

워드프레스: https://yaioyaio.wordpress.com/
티스토리 : http://senchatouch.tistory.com/

PhoneGap-1.7.0(Cordova) Eclipse Mac용 Android Tutorial Example


PhoneGap-1.7.0(Cordova) Eclipse Mac용 Android Tutorial Example

  1. 다음 이미지와 같은 예제를 만들 것이다. 지금 작성하는 모든 내용은 Cordova 사이트에 있다.
  2. 이클립스(Helios)를 실행한다.
  3. 안드로이드 프로젝트를 생성한다.

    다음 화면에서 프로젝트명을 다음과 같이 입력 한다. 그리고 Next 버튼을 클릭 한다.: Proejct Name – cordovaExample
    : Create new project in workspace 를 선택한다.
    : Use default location 을 체크한다.

다음 이미지와 같이 안드로이드 버전을 체크 한다.

지금부터 실습하는 내용은 폰에서 테스트 해야 하므로 되도록 사용 하고 있는 안드로이드 버전을 선택 하십시오.

지금 제작 하는 본인의 경우는 갤럭스 S2 아이스크림 버전이므로 화면과 같이 Android 4.0.3 을 선택 하였다.

그리고 Next 버튼을 클릭 하여 다음 단계로 넘어 간다.

이번 단계에서는 프로젝트의 기본적인 사항을 셋팅 할 차례이다.

입력할 내용은 다음과 같다.

: Application Name – CordovaExample

: Package Name – com.yaio.example

: Create Activity 를 체크 한다.

: Minimum SDK를 15로 선택 한다.

위와 같이 입력 하고 Finish 버튼을 클릭 하여 프로젝트 생성을 마무리 한다.

다음 이미지는 프로젝트 생성이 완료된 상태의 전체 구성이다.

  1. PhoneGap-1.7.0(Cordova)를 프로젝트 셋팅.
    – 이 전에 미리 실습을 하였던 방법과 같은 방법으로 Cordova의 파일을 프로젝트에 추가 한다.- 추가된 내용을 포함한 프로젝트 전체 구성은 다음 이미지와 같다.
  2. 프로젝트 코딩 및 실행.- 우선 AndroidManifest.xml 파일을 폰에서 사용할 수 있도록 퍼미션 부분등 몇 가지를 추가한다.

<?xml version=”1.0″ encoding=”utf-8″?><manifest xmlns:android=”http://schemas.android.com/apk/res/android“package=”com.yaio.example”android:versionCode=”1″

android:versionName=”1.0″ >

<uses-sdk android:minSdkVersion=”15″ />

<supports-screens

android:largeScreens=”true”

android:normalScreens=”true”

android:smallScreens=”true”

android:resizeable=”true”

android:anyDensity=”true” />

<uses-permission android:name=”android.permission.CAMERA” />

<uses-permission android:name=”android.permission.VIBRATE” />

<uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION” />

<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” />

<uses-permission android:name=”android.permission.ACCESS_LOCATION_EXTRA_COMMANDS” />

<uses-permission android:name=”android.permission.READ_PHONE_STATE” />

<uses-permission android:name=”android.permission.INTERNET” />

<uses-permission android:name=”android.permission.RECEIVE_SMS” />

<uses-permission android:name=”android.permission.RECORD_AUDIO” />

<uses-permission android:name=”android.permission.MODIFY_AUDIO_SETTINGS” />

<uses-permission android:name=”android.permission.READ_CONTACTS” />

<uses-permission android:name=”android.permission.WRITE_CONTACTS” />

<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />

<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />

<uses-permission android:name=”android.permission.GET_ACCOUNTS” />

<uses-permission android:name=”android.permission.BROADCAST_STICKY” />

<application

android:icon=”@drawable/ic_launcher”

android:label=”@string/app_name” >

<activity

android:name=”.CordovaExampleActivity”

android:label=”@string/app_name”

android:configChanges=”orientation|keyboardHidden” >

<intent-filter>

<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />

</intent-filter>

</activity>

</application>

</manifest>

자, 이번에는 index.html 파일을 만들어 보자.

다음 이미지에서의 방법과 같이 파일을 하나 생성하는 팝업창을 띄운다.

팝업창에서 index.html 파일명을 입력 하고 Finish 버튼을 클릭 한다.

프로젝트 생성을 하기 이전 실제 실행된 이미지를 처음에 봤다. 그와 같은 화면 구성을 하기 위해 CSS 를 먼저 만들어 보겠다.

CSS 파일을 생성 하는 방법도 위와 같은 방법으로 진행을 하면 된다.

새롭게 생성 하는 파일명을 master.css 로 한다. 그리고 내용을 다음과 같이 추가 한다.

  body {background:#222 none repeat scroll 0 0;color:#666;font-family:Helvetica;

font-size:72%;

line-height:1.5em;

margin:0;

border-top:1px solid #393939;

}

#info{

background:#ffa;

border: 1px solid #ffd324;

-webkit-border-radius: 5px;

border-radius: 5px;

clear:both;

margin:15px 6px 0;

width:295px;

padding:4px 0px 2px 10px;

}

#info > h4{

font-size:.95em;

margin:5px 0;

}

#stage.theme{

padding-top:3px;

}

/* Definition List */

#stage.theme > dl{

padding-top:10px;

clear:both;

margin:0;

list-style-type:none;

padding-left:10px;

overflow:auto;

}

#stage.theme > dl > dt{

font-weight:bold;

float:left;

margin-left:5px;

}

#stage.theme > dl > dd{

width:45px;

float:left;

color:#a87;

font-weight:bold;

}

/* Content Styling */

#stage.theme > h1, #stage.theme > h2, #stage.theme > p{

margin:1em 0 .5em 13px;

}

#stage.theme > h1{

color:#eee;

font-size:1.6em;

text-align:center;

margin:0;

margin-top:15px;

padding:0;

}

#stage.theme > h2{

clear:both;

margin:0;

padding:3px;

font-size:1em;

text-align:center;

}

/* Stage Buttons */

#stage.theme a.btn{

border: 1px solid #555;

-webkit-border-radius: 5px;

border-radius: 5px;

text-align:center;

display:block;

float:left;

background:#444;

width:150px;

color:#9ab;

font-size:1.1em;

text-decoration:none;

padding:1.2em 0;

margin:3px 0px 3px 5px;

}

#stage.theme a.btn.large{

width:308px;

padding:1.2em 0;

}

자, 이번에는 위에서 생성한 index.html 파일을 코딩을 하자. 다음의 내용을 그대로 복사해서 붙여 넣기를 한다.

<!DOCTYPE HTML><html><head><meta name=”viewport” content=”width=320; user-scalable=no” />

<meta http-equiv=”Content-type” content=”text/html; charset=utf-8″>

<title>PhoneGap</title>

<link rel=”stylesheet” href=”master.css” type=”text/css” media=”screen” title=”no title”>

<script type=”text/javascript” charset=”utf-8″ src=”cordova-1.7.0.js”></script>

<script type=”text/javascript” charset=”utf-8″ src=”main.js”></script>

</head>

<body onload=”init();” id=”stage”>

<h1>Welcome to Cordova!</h1>

<h2>this file is located at assets/www/index.html</h2>

<div id=”info”>

<h4>Platform: <span id=”platform”> &nbsp;</span>,   Version: <span id=”version”>&nbsp;</span></h4>

<h4>UUID: <span id=”uuid”> &nbsp;</span>,   Name: <span id=”name”>&nbsp;</span></h4>

<h4>Width: <span id=”width”> &nbsp;</span>,   Height: <span id=”height”>&nbsp;

</span>, Color Depth: <span id=”colorDepth”></span></h4>

</div>

<dl id=”accel-data”>

<dt>X:</dt><dd id=”x”>&nbsp;</dd>

<dt>Y:</dt><dd id=”y”>&nbsp;</dd>

<dt>Z:</dt><dd id=”z”>&nbsp;</dd>

</dl>

<a href=”#” onclick=”toggleAccel();”>Toggle Accelerometer</a>

<a href=”#” onclick=”getLocation();”>Get Location</a>

<a href=”tel:411″>Call 411</a>

<a href=”#” onclick=”beep();”>Beep</a>

<a href=”#” onclick=”vibrate();”>Vibrate</a>

<a href=”#” onclick=”show_pic();”>Get a Picture</a>

<a href=”#” onclick=”get_contacts();return false;”>Get Phone’s Contacts</a>

<a href=”#” onclick=”check_network();return false;”>Check Network</a>

<dl>

<dt>Compass Heading:</dt><dd id=”h”>Off</dd>

</dl>

<a href=”#” onclick=”toggleCompass();return false;”>Toggle Compass</a>

<div id=”viewport” style=”display: none;”>

<img style=”width:60px;height:60px” id=”test_img” src=”” />

</div>

</body>

</html>

자, index.html 과 master.css 파일을 생성 하고 소스 코딩을 하였다. index.html 파일의 내용을 보면 onClick에 해당 하는 각종 자바스크립트 함수가 있으며, 상단에 다음과 같은 자바스크립트 파일을 포함하고 있다.

<script type=”text/javascript” charset=”utf-8″ src=”main.js”></script>

이제는 main.js 파일을 새롭게 생성 하고 그 안에 소스 코딩을 해 봅시다.

main.js 파일도 위에서 생성한 방법과 마찬가지로 생성 하고 다음과 같이 소스를 코딩 한다.

var deviceInfo = function() {document.getElementById(“platform”).innerHTML = device.platform;document.getElementById(“version”).innerHTML = device.version;document.getElementById(“uuid”).innerHTML = device.uuid;

document.getElementById(“name”).innerHTML = device.name;

document.getElementById(“width”).innerHTML = screen.width;

document.getElementById(“height”).innerHTML = screen.height;

document.getElementById(“colorDepth”).innerHTML = screen.colorDepth;

};

var getLocation = function() {

var suc = function(p) {

alert(p.coords.latitude + ” ” + p.coords.longitude);

};

var locFail = function() {

};

navigator.geolocation.getCurrentPosition(suc, locFail);

};

var beep = function() {

navigator.notification.beep(2);

};

var vibrate = function() {

navigator.notification.vibrate(0);

};

function roundNumber(num) {

var dec = 3;

var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);

return result;

}

var accelerationWatch = null;

function updateAcceleration(a) {

document.getElementById(‘x’).innerHTML = roundNumber(a.x);

document.getElementById(‘y’).innerHTML = roundNumber(a.y);

document.getElementById(‘z’).innerHTML = roundNumber(a.z);

}

var toggleAccel = function() {

if (accelerationWatch !== null) {

navigator.accelerometer.clearWatch(accelerationWatch);

updateAcceleration({

x : “”,

y : “”,

z : “”

});

accelerationWatch = null;

} else {

var options = {};

options.frequency = 1000;

accelerationWatch = navigator.accelerometer.watchAcceleration(

updateAcceleration, function(ex) {

alert(“accel fail (” + ex.name + “: ” + ex.message + “)”);

}, options);

}

};

var preventBehavior = function(e) {

e.preventDefault();

};

function dump_pic(data) {

var viewport = document.getElementById(‘viewport’);

console.log(data);

viewport.style.display = “”;

viewport.style.position = “absolute”;

viewport.style.top = “10px”;

viewport.style.left = “10px”;

document.getElementById(“test_img”).src = “data:image/jpeg;base64,” + data;

}

function fail(msg) {

alert(msg);

}

function show_pic() {

navigator.camera.getPicture(dump_pic, fail, {

quality : 50

});

}

function close() {

var viewport = document.getElementById(‘viewport’);

viewport.style.position = “relative”;

viewport.style.display = “none”;

}

function contacts_success(contacts) {

alert(contacts.length

+ ‘ contacts returned.’

+ (contacts[2] && contacts[2].name ? (‘ Third contact is ‘ + contacts[2].name.formatted)

: ”));

}

function get_contacts() {

var obj = new ContactFindOptions();

obj.filter = “”;

obj.multiple = true;

navigator.contacts.find(

[ “displayName”, “name” ], contacts_success,

fail, obj);

}

function check_network() {

var networkState = navigator.network.connection.type;

var states = {};

states[Connection.UNKNOWN]  = ‘Unknown connection’;

states[Connection.ETHERNET] = ‘Ethernet connection’;

states[Connection.WIFI]     = ‘WiFi connection’;

states[Connection.CELL_2G]  = ‘Cell 2G connection’;

states[Connection.CELL_3G]  = ‘Cell 3G connection’;

states[Connection.CELL_4G]  = ‘Cell 4G connection’;

states[Connection.NONE]     = ‘No network connection’;

confirm(‘Connection type:\n ‘ + states[networkState]);

}

var watchID = null;

function updateHeading(h) {

document.getElementById(‘h’).innerHTML = h.magneticHeading;

}

function toggleCompass() {

if (watchID !== null) {

navigator.compass.clearWatch(watchID);

watchID = null;

updateHeading({ magneticHeading : “Off”});

} else {

var options = { frequency: 1000 };

watchID = navigator.compass.watchHeading(updateHeading, function(e) {

alert(‘Compass Error: ‘ + e.code);

}, options);

}

}

function init() {

// the next line makes it impossible to see Contacts on the HTC Evo since it

// doesn’t have a scroll button

// document.addEventListener(“touchmove”, preventBehavior, false);

document.addEventListener(“deviceready”, deviceInfo, true);

}

이제까지는 html, css, js 관련된 코딩을 마무리 하였다.

생성된 모든 폴더와 파일 구조는 다음 이미지와 같다. 지금까지 따라한 내용과 잘 맞는지를 확인해 보세요.

마지막으로 앱을 실행 하면 index.html 이 자동으로 실행이 되도록 CordovaExampleActivity.js 파일을 수정할 차례이다.

CordovaExampleActivity.js 파일은 위의 이미지에서와 같은 위치에 있다. 파일을 더블 클릭 하여 다음과 같이 수정을 한다.

package com.yaio.example;import android.app.Activity;import android.os.Bundle;// public class CordovaExampleActivity extends Activity {

public class CordovaExampleActivity extends DroidGap {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// setContentView(R.layout.main);

super.loadUrl(“file:///android_asset/www/index.html”);

}

}

그러면 아래의 이미지처럼 에러 표시가 날 것이다. 이런 에러는 import가 안 되어서 그런 것이니 키보를 다음과 같이 눌러 해당 하는 모듈을 import 하여 에러가 없어 지도록 합시다.

COMMAND + SHIFT + O – 필요한 모듈 자동 import 키보드 단축키.

다음 이미지는 에러가 없어진 상태의 소스 코드 이다.

자, 실제 모든 작업이 완료 되었다. 이제는 모든 것을 저장 하고 실행을 해 보도록 합시다.

앞으로 우리가 하나 씩 찾아 볼 Cordova에서 제공 하는 함수들을 알아 보기 이전에 전체적인 내용이 들어간 간단한 예제를 한 것이다.

정확히 어떤 것이 어떤 역활을 하는지 대하여 여기서 설명을 하지 않겠다. 단지, 하이브드리앱 개발을 시작 하기 이전에 Cordova에서 제공 하는 것들을 간단하게 경험을 할 뿐이다.

다음에 보여 주는 이미지들은 갤럭시 S2에서 실행한 화면을 캡쳐한 내용이다.

일부 캡쳐를 할 수 없는 것도 있지만 참고 하시기를 바란다.

위의 이미지는 다시 한번 말씀 드리지만, 갤럭시 S2에서 실행한 화면들이다.

아이폰용은 폰이 준비 되는 데로 테스트 하여 올려 드리겠습니다.

다음 시간에는 Cordova 에서 제공 하는 각 함수를 천천히 살펴 보기로 하자.
다음 내용은 Cordova에서 제공 하는 기능들이다.

  1. Accelerometer
  2. Camera
  3. Capture
  4. Compass
  5. Connection
  6. Contacts
  7. Device
  8. Events
  9. File
  10. Geolocation
  11. Media
  12. Notification
  13. Storage

프로필.
소속: (주)애드웹커뮤니케이션부서 : 개발팀직위: 팀장이름 : 안병도(꼬장)

메일 : yaio@naver.com,
yaioyaio@gmail.com,
program@adweb.co.kr

네이버카페 : http://cafe.naver.com/mobilewebapp

트위터 : @yaioyaio

페이스북 : http://www.facebook.com/byoungdo.ahn
페이스북그룹 : http://www.facebook.com/groups/korea.sencha/

워드프레스: https://yaioyaio.wordpress.com/
티스토리 : http://senchatouch.tistory.com/

PhoneGap-1.7.0(Cordova) XCode 4.2 iOS Tutorial 기본 사용법


PhoneGap-1.7.0(Cordova) XCode 4.2 iOS Tutorial기본 사용법

  1. phonegap-1.7.0(Cordova)을 사용 하기 위한 요구 사항.
    – Mac OSX Lion(10.7)
  2. Install SDK + PhoneGap-1.7.0(Cordova)
    – Install Xcode.
    : Mac App Store.- PhoneGap-1.7.0(Cordova) 다운로드
    : http://phonegap.com/download
             : 위의 주소에서 phonegap 관련 자료를 다운로드 받자.
    다음 이미지와 같이 다운로드 폴더에 있을 겁니다. 다운로드 받은 파일의 압축을 해제 한다.

    : 압축을 해제한 다음 폴더의 내용을 계속해서 사용을 할 것이니 잘 정리해서 보관해 두자. 다음과 같은 형태의 폴더 구조를 볼 수 있다.

    : 위의 이미지에서 Cordova-1.7.0.dmg 파일을 더블 클릭 하여 압축 해제를 합니다.
    다음 이미지와 같이 팝업창에서 Cordova-1.7.0.pkg 파일을 더블 클릭 하여 프로그램을 설치 한다.

    : 다음 이미지에서 계속을 클릭 하여 다음 단계로 넘어 간다.

    : 설치가 완료 되면 다음 이미지에서 닫기를 클릭 하여 설치를 완료 한다.

  3. PhoneGap-1.7.0(Cordova) New Project.- 먼저 Xcode를 실행 한다.

    – 위의 이미지에서 첫 번째 메뉴인 “Create a new Xcode project”를 클릭 한다. 다음 이미지와 같이 창이 뜬다. 이 창에서 이미지에서 처럼 “Cordova-based Application”를 클릭 한다.


    – 다음 이미지와 같이 프로젝트명을 입력한다. 그리고 Next 버튼을 클릭 하여 다음 단계로 넘어 간다.

    : Project Name – MyPhoneGapApp
    : Company Identifier – com.phonegap
    : Use Automatic Reference Counting 을 체크 하지 않는다.

    – 이 번 단계에는 폴더를 생성 하는 단계이다. 다음 이미지의 하단에 있는 New folder 버튼을 클릭 하자.

    – 다음과 같은 팝업창에 폴더명을 입력 하자. 이미지와 같이 입력을 하셔도 되고, 사용자 편의에 맞게 입력을 하여도 무방하다. 그리고 Create 버튼을 클릭 하여 프로젝트 생성을 마무리 한다.

    : Name od new folder – MyPhoneGapApp

    – 다음 이미지는 프로젝트 마무리 이후 첫 Xcode 화면의 모습이다.

    이제는 실제 PhoneGap-1.7.0(Cordova)를 이용한 코딩과 실행을 할 차례이다.

  4. Xcode 4.2에서의 PhoneGap-1.7.0(Cordova) 코딩과 실행.- 마지막 프로젝트 셋팅이 완료 되면 화면 중간에 빨간색으로 에러가 있다는 내용이 표시 된다.(만약 이 부분이 없는 사용자는 하지 않고 건너 띄어도 무방하다.)
    물론 프로젝트 폴더가 보이는 왼쪽에도 보이고, 상세 정보가 나오는 가운데 상단에도 보인다.

    에러의 내용은 간단하게 다음 이미지처럼 몇 군데에서 보인다.


    – 소스에서도 확인이 가능하다.

    위의 이미지 중 첫 번째에서 main.m 부분을 더블 클릭 하면 새창으로 소스가 보이면서 에러가 있는 부분을 보여 준다.

    그 내용은 다음 이미지와 같다.

    무엇이 원인인지는 잘 모르겠지만 다음과 같이 수정을 하면 없어진다.

    프로젝트의 Supporting Files 폴더에 main.m 파일이 있다. 그 파일을 더블클릭 하여 에디창으로 열어서 수정을 해도 된다.

소스의 31번 라인을 다음과 같이 수정한다. 간단하다 주석 처리하는 것이다.//    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

int retVal = UIApplicationMain(argc, argv, nil, @”AppDelegate”);

소스의 33번 라인을 다믕과 같이 수정한다. 간단하다 주석 처리하는 것이다.

//    [pool release];

return retVal;

자, 이번에는 AppDelegate.m 파일을 열어서 에러 있는 부분을 수정을 할 것이다.

소스의 72번 라인을 다음과 같이 수정.//    self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease]; 이 부분을 주석 처리 하고 다음과 같이 변경 한다.

self.window = [[UIWindow alloc] initWithFrame:screenBounds];

소스의 78번 라인을 다음과 같이 수정.

//    self.viewController = [[[MainViewController alloc] init] autorelease]; 이 부분을 주석 처리 하고 다음과 같이 소스를 변경한다.

self.viewController = [[MainViewController alloc] init];

소스의 137번 라인을 다음과 같이 수정.

– (void) dealloc

{

//    [super dealloc]; 이 부분을 주석 처리 한다.

}

이제껏 수정한 내용을 저장 하고 Build를 해 보도록 하자.

빌드를 하기 이전에 다음 이미지와 같이 실행 할 시뮬레이터 버전을 먼저 선택을 한다.

위의 이미지처럼 선택을 완료 하였으면, 왼쪽에 보이는 Run 버튼을 클릭 하여 문제 없이 실행이 되는지 확인을 해 보도록 합시다.

꼭 한번은 해야 할 과정이니 빠트리지 말자. 먼저 Run 을 실행한다.

이렇게 Run 을 아무런 작업 없이 먼저 하는 이유는 나중에 알 수 있겠지만 www 폴더를 찾아 가는 과정이 생기는데 지금 프로젝트에는 포함 되어 있지 않다.

그래서 먼저 Run 을 실행 하고 나면 프로젝트 폴더에 www 이 생기고, 자동으로 index.html 파일과 cordova-1.7.0.js 파일이 같이 생성 된다.

그렇게 생성된 www 폴더를 이후의 작업에서 프로젝트에 포함 시키는 차례가 있다. 그곳에서 이번에 생성 되는 www 를 포함 시키는 방법을 알아 볼 것이다.

아래 이미지 중 왼쪽은 로딩 화면이고, 오른쪽은 실제 앱의 첫 화면이다.

아직은 하이브리드 앱을 제작 하는데 필요한 html 문서가 없기 때문에 찾지 못 한다는 내용의 에러가 보인다.

이제는 하이브리드 앱을 개발 하는데 필요한 작업을 할 차례이다.

우선은 작업에 필요한 파일을 다음 이미지와 같은 방법으로 추가를 할 것이다.

프로젝트에서 다음 이미지처럼 마우스를 이용하여 따라 해 보자.

위와 같이 하면 팝업창이 열릴 것이다. 내용은 다음 이미지와 같다.

자 위에서 보이는 화면의 내용 중 www 라고 되어 있는 폴더를 프로젝트에 추가할 것이다.

다음 이미지에서 보는 것처럼 마우스를 사용 하여 www 폴더를 끌어다 놓는다.

다음 이미지 처럼 보이는 상태에서 Finish 버튼을 클릭 하여 추가 하는 작업을 마무리 한다.

위와 같이 모든 작업이 완료 되었다면 다음 이미지와 같은 상태가 프로젝트에 보일 것이다.

자, 이제는 마지막으로 잘 실행이 되는지 빌드를 해 볼 차례이다. 각자 직접 시뮬레이터로 해 보기를 바란다. 하기에 보이는 이미지와 같이 잘 실행이 될 것이다.

지금까지 Mac에서 Xcode로 하이브리드 앱을 만들기 위해 PhoneGap-1.7.0(Cordova)의 사용법을 간단하게 알아 보았다. 어려운 곳은 없었으니 충분히 잘 따라 하셨을 것이다.

다음 시간에는 예제를 통하여 Cordova에서 하이브리드 앱 제작에 필요한 기능들을 하나 씩 알아 볼 것이다.

다음 내용은 Cordova에서 제공 하는 기능들이다.

  1. Accelerometer
  2. Camera
  3. Capture
  4. Compass
  5. Connection
  6. Contacts
  7. Device
  8. Events
  9. File
  10. Geolocation
  11. Media
  12. Notification
  13. Storage

프로필.
소속: (주)애드웹커뮤니케이션부서 : 개발팀

직위: 팀장

이름 : 안병도(꼬장)

메일 : yaio@naver.com,
yaioyaio@gmail.com,
program@adweb.co.kr

네이버카페 : http://cafe.naver.com/mobilewebapp

트위터 : @yaioyaio

페이스북 : http://www.facebook.com/byoungdo.ahn
페이스북그룹 : http://www.facebook.com/groups/korea.sencha/

워드프레스: https://yaioyaio.wordpress.com/
티스토리 : http://senchatouch.tistory.com/