차례 서버의 Bookmarks OData 서비스호출하기 145 데이터베이스관리하기 153 SqlStatement 클래스와 ISqlStatementSource 인터페이스 156 테이블생성하기 158 Sqliteman 으로데이터베이스검사하기 161 데이터베이스에즐겨찾기쓰기 165 즐겨찾기읽기와내비게이터에표시하기 171 정리 177 CHAPTER 7 안드로이드 : 변경내용을서버로푸시하기 179 로컬의변경내용캡처하기 180 SQL 필터를제한하기 180 삭제된엔터티를뷰에서제외하기 186 즐겨찾기를오디널별로가져오기 187 구성폼빌드하기 188 싱글턴구성하기 212 변경내용을서버로푸시하기 221 로컬의변경내용파악하기 221 삽입, 업데이트, 삭제를서버에요청하기 226 HTTP MERGE 로업데이트하기와 HTTP POST 로삽입하기 227 필드를서버에서사용할수있도록표시하기 227 정리 238 vii
아이폰과안드로이드기반의 CHAPTER 8 ios: 툴셋설치하기 239 아이패드개발 239 Xcode 설치하기 239 닷넷및자바개발자를위한오브젝티브 -C 입문과정 240 오브젝티브 -C의문제점들 241 메서드호출하기 ( 일명 메시지보내기 ) 242 프로퍼티 ( 그리고간략히언급하는메모리관리 ) 245 메서드 252 네임스페이스 254 오브젝티브 -C에서가장골치아픈점 254 아이폰용 Hello, World 255 사용자인터페이스구성하기 257 윈도우생성하기와뷰보여주기 264 정리 267 CHAPTER 9 ios: 로그온폼작성하기와 REST 서비스소비하기 269 프로젝트생성하기 269 로그온폼 270 로그온폼사용자인터페이스생성하기 271 로그온폼보여주기 275 그룹화뷰에관한특강 278 코드표현규칙 279 서비스호출하기 280 로그온요청캡처하기 280 API 서비스호출하기 286 프록시클래스작성하기 287 Users 서비스호출하기 318 진행중임을알리기 325 viii 정리 327
차례 CHAPTER 10 ios: SQLite 의 ORM 레이어 329 잠시짚고넘어가야할이야기 330 엔터티 330 SBEntityType 클래스 330 SBEntity 클래스 339 엔터티에값설정하기 342 SBBookmark 작성하기 347 SBEntityType 인스턴스생성하기 350 짝퉁즐겨찾기표시하기 352 뷰생성하기 352 뷰엔진빌드하기 357 즐겨찾기표시하기 362 내비게이션처리하기 365 Sync 클래스빌드하기 367 서버의 Bookmarks OData 서비스호출하기 367 데이터베이스작업 384 SBDBHelper 빌드하기와오류처리구현하기 386 데이터베이스에즐겨찾기쓰기 401 정리 421 CHAPTER 11 ios: 변경내용을서버로푸시하기 423 즐겨찾기구성하기 423 데이터를테이블에넣기 426 즐겨찾기정렬하기 430 싱글턴뷰 431 즐겨찾기편집하기 437 삭제메서드구현하기 444 즐겨찾기추가하기 445 ix
즐겨찾기삭제하기 447 아이폰과안드로이드기반의 수동으로동기화하기 451 변경내용을서버로푸시하기 452 작업항목 455 OData 변경요청하기 460 서버에없음 으로필드지정하기 462 요청생성하기 463 processworkitems 수정하기 470 정리 472 CHAPTER 12 ios: 모노터치 473 큰틀에서본모노 474 이장의구성 475 모노터치설치하기 475 Hello, World 476 코드비하인드검사하기 480 버튼연결하기 481 프로젝트실행하기 483 Six Bookmarks API 의 RESTful 서비스호출하기 484 프로젝트생성하기 484 ServiceProxy 등등을빌드하기 484 서비스메서드호출하기 490 정리 494 찾아보기 495 x
역자머리말 아이폰과안드로이드기반의크로스플랫폼앱개발 국토해양부에따르면 2010 년 12 월우리나라에등록된전체자동차수가 1,794 만대라고한다. 자동차를소유하고나서누리는생활은그전과사뭇다르다. 더나아졌다기보다는행동 반경이넓어져그만큼다양한경험을누릴수가있다는점은분명하다. 자동차와직접적으로 비교하기에는무리가있지만스마트폰또한우리의삶속으로깊이들어와많은변화를이끌어 냈다. 올해안으로스마트폰보급대수가 2 천만을넘길것이라는언론보도만봐도스마트폰이 우리의삶에얼마만큼영향을미칠지는어림짐작할수있다. 이미스마트폰은단순한흥밋거리 를제공하는수단을뛰어넘어문화를누릴수있는도구가됐고, 스트레스를해소할수있는 도구로도, 나아가학습의도구로도자리매김한지오래다. 물론스마트폰이주는스트레스도 만만치않지만말이다. 스마트폰이우리생활속으로깊이파고들면서관련시장도커졌고, 앞으로더커질것이라는 전망에이의를제기하는사람은거의없다. 자동차를구입하고달랑자동차만운행하는사람이 없듯, 우리는스마트폰을구입하면케이스나보호필름, 열쇠고리등액세서리로예쁘게꾸며주 고, 다양한콘텐츠를즐기기위해유료앱을구입한다. 스마트폰이라는하드웨어비용보다더 많은비용을앱에지불하는경우도어렵지않게찾아볼수있다. 그래서앱시장또한폭발적으 로커지고있고, 얼마나많은앱이있느냐가스마트폰을선택하는기준중의하나가되는현실 에서, 나도멋진앱을만들고싶다고미래의계획을세우는사람또한많아졌다. 안드로이드와 ios 가 펩시와코카콜라 가될것이라는저자의예상처럼, 우리가접하는수많은 앱은대개이두종류에속한다. 이책은동일한앱을이쪽에서는어떻게접근하고저쪽에서는 접근하는지꽤깊이있게보여준다. 원저서가출간된지시간이많이흘렀지만, 이쪽에서는 어떻게접근하고저쪽에서는어떻게접근하는지에관한이책의주제는빛이바래지않는다고 생각한다. 다만, 1 장의경우흘러간옛이야기여서현재상황을반영하지못한다. 그러나지금 으로부터 1 년전모바일을둘러싼세상이어떻게돌아갔는지돌이켜보면지금의세상도이해하 기쉬워지고, 나아가앞으로어느방향으로흘러갈지도예측해보는데적잖은도움이되리라 생각한다. 이번역서에서안드로이드는 2.3 진저브레드에서모두테스트를하였고, 아이폰개발 부분은 Xcode 4 파이널버전, ios SDK 4.3 으로, 그리고모노터치는최신버전인 4.0.3 으로 업데이트하였음을밝혀둔다. xi
역자머리말 아이폰과안드로이드기반의크로스플랫폼앱개발 하루가다르게, 아니한시간이다르게쏟아져나오는최신용어를일일이온전한우리말로대체하기가쉽지않은것은원문을우리말로옮기는입장에서변명이지만사실이다. IT 용어가일부를제외하면지극히평범하고쉬운단어로표현된다는점을고려하여용어자체는그대로가져다써도문장의표현만큼은쉽게다갈수있도록정성을기울였으나어떻게받아들여질지걱정이앞선다. 아무쪼록편하게읽히기를바랄뿐이다. 이책에서가장중요한곳은 2장과 3장이다. 세부코드내용에더많은관심을두는독자라면안드로이드의 4장에서 7장까지, ios의 8장에서 11장까지가더큰관심을불러오겠지만, 앱개발의방향과접근방식을이해하려면 2장과 3장이가장중요하다고할수있다. 또한처음부터차근차근읽지않는경우에는안드로이드와 ios의각장에서서로대응되는곳을비교해가며읽는것도괜찮은접근방식이라고생각한다. 펩시가됐든코카콜라가됐든, 소비자입장에서야자신의기호에맞는제품을선택하면그뿐이고, 제조회사는타사와의경쟁에서우위를점하기위해각고의노력을하겠지만, 앱을개발하는입장에서는뛰어나고멋진아이디어를어느한운영체제용으로만개발하여시장에내놓을이유는없다. 한쪽에익숙하고다른쪽에낯설다하여어느한쪽만고집할이유도없고, 어느한쪽이더낫다고옹호하거나반대로폄하할이유도없다. 아무쪼록이책으로인해여러분의뛰어나고멋진아이디어가사용자에게편리함을제공할수있도록활용되기를바랄뿐이다. 책을읽다가궁금한점이생기면저자의트위터 (@mbrit) 로문의해도되고, 역자의이메일 (JustDoIt709@gmail.com) 로문의해도된다. 트위터라는훌륭한의사소통수단덕분에시간대만맞으면언제든지직접저자에게문제해결을위한조언을거의실시간으로얻을수있다. 끝으로이책이나올수있도록믿고지켜봐주신장성두실장님께정말큰고마움을드린다. 달리고마움을표현할단어가마땅치않아아쉬울뿐이다. 그리고사랑하는아내와딸서정이에게도고마움을전한다. 컴퓨터앞에만앉아서많이놀아주지도못한아빠를이해해주고, 위로까지해준소중한딸이다. 아무쪼록이책이독자들에게가치있게활용되기만을바란다. 2011년 6월배장열 xii
저자소개 아이폰과안드로이드기반의크로스플랫폼앱개발 매튜박스터레이놀즈 Matthew Baxter-Reynolds 매튜박스터레이놀즈는소프트웨어개발컨설턴트로서현재팀구조에서최대의성과를끌어낼수있도록컨설팅하고있다. 공개표준, 마이크로소프트서버, 모바일플랫폼의 빅 4 에특별히관심이많다. 강사로서다수의개발관련책을집필한저자이기도하다. 현재영국에거주하며, 모바일기술솔루션을주업무로하고있다. LinkedIn 사이트인 www.linkedin.com/in/mbrit 로연락을주고받을수있으며, 이책과관련된이야기는 http://www.multimobiledevelopment.com/ 을통해나누고있다. xiii
기술검토자소개 아이폰과안드로이드기반의크로스플랫폼앱개발 매트피체트 Matt Fitchett VB.NET 경험이풍부한매트는 2004년에 DVD/CD 중심의작은전자상거래회사 (play.com) 에합류하여 C# 을다뤘다. play.com 은소프트웨어개발자인매트의중추적인역할에힘입어유럽에서가장큰전자상거래회사중하나로성장했다. 매트는 6년반동안의즐거운경험을마무리하고모바일기술을전문적으로다루기로정했다. 소프트웨어개발자나기업을위한중대한성장분야라는인식이있었기때문이다. 매튜박스터레이놀즈와함께일하면서매트는다양한기술플랫폼 ( 안드로이드, 아이폰, 윈도우폰 7 등 ) 의프로토타입을만들어내며모바일설문조사소프트웨어시장을선도했다. 매트와그의사랑하는아내사라 (Sarah) 는어린아들, 아이작 (Issac) 을두었고, 에드문즈의한아름다운도시에살고있다. 매트는영화, 게임, 음악을즐기며, 맛좋은음식을곁들인맥주를좋아한다. 그리고규칙적으로무에타이를연마하고있다. 그가운영중인블로그인 www.mattfitchett.com 에는모바일기술에관한논의를포함하여그가즐기는여러가지가모두담겨있다. xiv
감사의글 아이폰과안드로이드기반의크로스플랫폼앱개발 내아내인앤디 (Andy) 에게크나큰고마움을전한다. 책을쓰는동안인내와지원을보여주었다. 그리고이책을검토하고탁월한제안을서슴지않았던매트피체트 (Matt Fitchett) 와조너선하셀 (Jonathan Hassel), 아니타카스트로 (Anita Castro) 등 Apress의여러관계자분들에게감사의말을전한다. 그들의뛰어난노력이없었다면이책은세상에나오지못했을것이다. xv
CHAPTER 2 Six Bookmarks 의서버서비스 Six Bookmarks 애플리케이션의아키텍처나스펙에관해서는 3장에서좀더이야기하기로하고, 이장에서는관련서비스를들여다보기로하자. 일단이책에서사용할서버를설치해놓았다. REST 기반 (RESTful 이라고도함 ) 서비스를제공하는이서버는 Six Bookmarks 애플리케이션의로그온을처리하고, 즐겨찾기를검색하여업데이트가있으면이를다시애플리케이션에보낸다. 이과정에서서버는 OData 프로토콜을사용하여모든작업을처리한다 (OData 프로토콜에관해서는뒷부분에서상세하게다룰것이다 ). 앞에서말한대로 Six Bookmarks 는두가지방식으로제공되는상용제품이다. 한가지방식은일반적인상용제품이고, 다른한가지는오픈소스제품인데, 이책에서는오픈소스버전기반의서비스에액세스한다. 그리고두애플리케이션모두공용서버와통신한다. 우리가사용할오픈소스서버는샌드박스 (sandbox) 역주1 를지원하며, 앞으로진행할서버작업을위해새로운계정이필요하다. 1) 역주 1 샌드박스는외부에서들어온프로그램이보호영역에서동작하면서시스템을임의로조작하지못하도록막는보 안형태를말한다.
8 CHAPTER 2 Six Bookmarks 의서버서비스 요즘, 클라우드 에관한이야기나 클라우드에 데이터를저장하는것에관한이야기가정말많다. Six Bookmarks 의서버서비스는일종의 클라우드 서비스로서, 이책에서사용할서버는공용인터넷에호스트되어 클라우드에 즐겨찾기를저장하거나다시 클라우드에서 즐겨찾기를검색한다. 이런서비스를구성하는방법은이책에서다루지않겠지만, 해당소스코드는 http://code. multimobiledevelopment.com/ 에서다운로드할수있다. 역주2 이코드나그밖의다른코드들은모질라공개라이선스 1.1(Mozilla Public License 1.1) 에따라배포된다. 보다자세한내용은 www.mozilla.org/mpl/mpl-1.1-annotated.html 에잘설명되어있다. 2) API 계정만들기 API 계정을생성하려면 http://services.multimobiledevelopment.com/ 을방문한다. 화면에표시되는페이지에서 Register a new API account( 새 API 계정등록 ) 링크를클릭하면그림 2-1과같은등록페이지가나타난다. 이사이트 (http://services.multimobiledevelopment.com) 는지금도계속변화하고있다. 따라서이책에제공된스크린샷중일부는현재제공하는웹페이지와다를수있다. 그리고이사이트는테스트용이라서 HTTPS 로액세스하더라도보안이유지되지않는다. 제품애플리케이션을제작할경우에는보안설정과정을염두에두어야한다. 이제사이트에접속해서계정을만들어보자. 이메일주소를올바로입력하면나중에비밀번호를재설정할때요긴하게사용할수있으니, 스팸메일을걱정하느라이상한주소를입력하지말길바란다. Register Account( 계정등록 ) 버튼을클릭하면등록과동시에자동으로로그온된다. 역주 2 이웹페이지의맨아랫부분에 Services 항목이있다. 설명부분의 http://github.com/mbrit/amxmobile.services- 1.1/downloads 링크를클릭하면소스코드를다운로드할수있다.
API 계정만들기 9 그림 2-1 등록페이지 사용자만들기 계정을등록해야데이터베이스에사용자데이터를저장하기위한고유공간을할당받을수있다. 서버에는단일 SQL Server 데이터베이스가존재하고, 이데이터베이스에사용자정보나즐겨찾기가저장되는데, 이는애플리케이션과조금다른상황일수있다. 여기서는이책을하나하나따라가며실제애플리케이션을작성하는과정이보다쉬워질수있도록샌드박스서비스를제공할것이다. 그러나제품애플리케이션에서는이서비스가별로필요하지않다. 데이터손상이나비정상적동작을막으려면독자들의데이터를개별 가상데이터베이스 로분리해야한다. 그러나물리적으로분리된데이터베이스를생성하여수만명의데이터를처리하는것은실용적이지못하다.
10 CHAPTER 2 Six Bookmarks 의서버서비스 따라서여기서는 ApiKeys, Users, Bookmarks 등세가지테이블로작업할텐데, 다음의그림 2-2 에 이테이블들의개체 - 관계다이어그램 (ERD, Entity-Relationship Diagram) 을나타내었다. ApiKeys Users Bookmarks PK ApiKeyld PK Userld PK Bookmarkld Username PasswordSalt PasswordHash FK1 ApiKeyld Username PasswordSalt PasswordHash FK1 Userld Name Url Ordinal 그림 2-2 ApiKeys 테이블, Users 테이블, Bookmarks 테이블사이의관계를보여주는 ERD API 계정을등록한다고해서사용자가저절로만들어지는것은아니다. 이쯤해서사용자라는용어를정리해보자. 여기서는모바일용 Six Bookmarks 애플리케이션을자신의장치에서사용하게될사람을의미한다. 사용자를만들려면 Manage Users( 사용자관리 ) 링크를클릭한다. 현재사용자가등록되어있지않으므로그림 2-3처럼사용자가없다는메시지를받게된다. 그림 2-3 현재사용자가없음을알리는 Manage Users( 사용자관리 ) 페이지 Add a new user( 새사용자추가 ) 링크를클릭하면, 그림 2-4 와같은페이지가나타난다.
Users 서비스 11 그림 2-4 Edit User( 사용자정보수정 ) 페이지 적어도한명의사용자를생성해야다음단계로진행할수있다. Users 서비스 Users( 사용자 ) 서비스는 RESTful 웹서비스로서, 사용자를로그온해줄수있는기능을제공한다. 이책에서는사용자를로그온해주는기능만을다루지만, 사용자등록등다른기능을제공하는서비스도가능하다. 서버가어떻게동작하는지충분히숙지하고있어야앞으로작성할애플리케이션의흐름을이해하기가한결수월해진다.
12 CHAPTER 2 Six Bookmarks 의서버서비스 RESTful 웹서비스 RESTful 웹서비스는 REST 원칙에따른서비스로서, REST란 Representational State Transfer 를일컫는다. REST는공식적인표준프로토콜은아니지만일련의원칙및제약조건의집합으로서, 데이터를가져오거나제공할수있는서비스를구성한다. 또한 REST는원격서비스를작업하기에는매우자연스러운방법인데, 바로이점이큰인기를끌고널리사용되는이유다. 이러한자연스러움이구축하기도편하게할뿐더러소비하기도편하게한다. RESTful 웹서비스를매우직관적으로구축할수있는손쉬운방법은 HTTP GET 요청을사용하고, 그결과를 XML로받아데이터를요청하는것이다. HTTP 요청은쿼리문자열에명시한파라미터를포함하는 GET 요청이될수도있다. 또는 XML을전달하는 POST 요청에도파라미터가포함될수있다. 계속해서사용자서비스의로그온과정을보다상세히들여다보기로하자. 호출테스트하기 여기에쓰일 API는커스텀 HTTP 헤더를전송하는과정에의존하기때문에일반적인웹브라우저에서는테스트할수없다. 따라서서비스를호출하기위한커스텀코드를작성하지말고, 테스트용도구를다운로드해서서비스를시도해보아야한다. 이도구는 http://services.multimobile development.com/ 의첫화면에서 API REST Web service 의 Documentation 링크를클릭한다음, Downloads 탭을클릭하거나직접 http://code.google.com/p/sixbookmarks/downloads/list 를입력하면압축파일을찾을수있다. 찾아야할테스트용도구는닷넷애플리케이션으로서파일명은 AmxMobile.Services-<Version>-TestClient.zip 이다. 역주3 3) 이유틸리티를실행하면 API username header 와 Token header 를입력하는필드, URL을입력하는필드가보일것이다. 이두필드에관해서는나중에다시다루겠지만, 일단응답을안내하기위한추가정보를제공하는곳이라고만이해해두자. 역주4 4) 로그온작업검사하기 사용자서비스로맨먼저시도할것은사용자를로그온하는것인데, 제대로로그온한다면그다 음요청에사용할수있는토큰을받게된다. 역주3 원서에표시된주소와달라진부분도있고, 사이트의구성도사뭇달라졌다. 찾아야하는파일명은 2010 년 6월에업로드된 AmxMobile.Services-1.0.40611.2208-TestClient.zip 이다. 역주4 압축파일을풀면여러파일이풀려나오는데, 그중에서 AmxMobile.Services.TestClient.exe 를실행한다.
Users 서비스 13 테스크도구를열면다음과같이미리입력된 URL 필드를확인할수있다. http://services.multimobiledevelopment.com/services/apirest.aspx?operation= logon&password=apipassword Send Request( 요청전송 ) 버튼을클릭하면그림 2-5 와같은응답결과를얻는다. 그림 2-5 API 서비스에대해실패한요청 그림과같이오류가반환된결과를확인할수있다. 예외가 Error 요소에다시반환되는것, 그리고오류가반환되면 HasException 요소가 true로설정되는것이 REST 서비스를위한프로토콜에해당한다. XML에나타난값은 1이지만, datatypes 스키마는 1을불린값으로이해한다. 이와같은오류알림및전송서비스는필자가디자인한것으로서, RESTful 웹서비스는이런 접근방식을사용하지않는다. 전형적인 RESTful 서비스의느슨한구조 (construct) 안에서합 리적이고논리적인프로토콜을디자인하는것은서비스의소유자가할일이다. 다시그림 2-5 로돌아가자. 표시된오류내용은 Neither a logon token nor API key were provided in this request( 로그온토큰및 API 키가이요청으로는제공되지않습니다 ) 인데, 헤더가
14 CHAPTER 2 Six Bookmarks 의서버서비스 서버에제공되지않았음을나타낸다. 서버의작업을호출하려면토큰이필요하다. 그런데토큰을얻으려면서버를호출해야하니이런경우를두고닭이먼저냐달걀이먼저냐고할수도있겠다. 그러나서버의어떤작업은토큰이필요하지않는데, 바로 API 서비스의 Logon 작업이다. 이작업은다른메서드와사용하기위한토큰을얻는데에만사용된다. 토큰얻기이테스트용도구를실행하면 API 서비스에연결하여 Logon 메서드를호출하는것이기본값이다. 먼저 API username header에조금전만든계정을입력하고, URL에서 password 값에해당비밀번호를입력한다. 제대로입력했다면 Send Request 버튼을클릭하자. 그림 2-6과같은결과를얻을수있을것이다. 그림 2-6 API 서비스에대해성공한요청 Result 요소를확인하면 LogonOk 라고표시되어오류가반환되지않은것을확인할수있다. 비밀번호를잘못입력했다면 LogonOk 가아니라 InvalidPassword 가표시된다. 여기에서가장중요한요소는 Token으로서, 다른모든요청에사용할토큰이다. 이토큰을복사하여 Token header에붙여넣기하자. 이토큰은곧사용하게된다.
Users 서비스 15 사용자로그온해주기 이제사용할토큰을얻었고 API 도인증했으니, 실제로사용자를로그온해줄수있다. 지금까지는 API 서비스를사용했고, 이제부터는 Users 서비스를사용할것이다. 테스트용도구에서 User Logon 링크를클릭하면 URL 이다음과같이바뀐다. http://services.multimobiledevelopment.com/services/usersrest.aspx?operation= logon&username=username&password=password Users 라는 REST 서비스를호출할수있도록 URL 이이렇게구성된것이다. 이문자열의 USERNAME 과 PASSWORD 부분을앞에서만든사용자명과비밀번호로바꾸고, 토큰을제대 로복사하여붙여넣기했다면그림 2-7 과같은결과를확인할수있을것이다. 자신있게 Send Request 버튼을클릭하자. 그림 2-7 Users 서비스에대한요청이성공한응답 여기까지잘따라왔다면 LogonOk 응답을확인할수있을것이다. 여기서 LogonOk 는여러분이인증한사용자에게토큰이바인딩되었음을나타낸다. 지금이이야기는굉장히중요하다. 왜냐하면동일한토큰을다른사용자에게사용할수없다는의미이기때문이다. 모바일기기에서는이것이별로문제가되지않지만, 웹애플리케이션에서는이점을신중하게고려해야한다. 다시본론으로돌아가면, 응답으로받을수있는결과에는 InvalidUsername, InvalidPassword, AccountInactive 가있다.
16 CHAPTER 2 Six Bookmarks 의서버서비스 서비스해지하기서비스를해지하려면 API에서로그오프해야한다. 이때사용되는것이 Logoff 작업이다. 테스트용도구에서 API logoff 링크를클릭하면 URL이새롭게표시된다. Send Request 버튼을클릭하면그림 2-8과같은응답을확인할수있다. 그림 2-8 API 서비스에대한 로그오프 호출이성공한응답 Logoff 작업은서버가토큰에바인딩자원들을깨끗하게청소 ( 해지 ) 할수있는기회로사용된다 ( 구체적으로말하면데이터베이스에서한행을삭제하는것이다 ). 토큰청소에대해서는네이티브애플 리케이션을작성하는곳에서보다자세하게다루겠다. Bookmarks 서비스 서버에서이루어지는마지막서비스는 Bookmarks OData 서비스이다. OData 는한창떠오르고있는데이터포맷으로서, 웹 2.0 세상에서데이터교환의실질적인표준으로확실하게자리를잡아가고있다. 개인적으로 OData 는훌륭하고실용적인작업방식을갖춘제대로된표준이라고생각한다. 그래서클라우드에저장된관계형데이터와디바이스에저장된데이터사이에서다리구실을하도록 OData 를이책에서사용했다.
Bookmarks 서비스 17 OData 를더욱자세하게알고싶다면공식사이트인 http://www.odata.org/ 를방문하는것도 좋은방법이다. 테스트데이터추가하기 OData 서비스의동작방식을확인하기위해서몇가지테스트데이터가필요하다. 그리고사용자별즐겨찾기를유지관리하는서비스에는인터페이스가존재한다. services.multimobiledevelopment.com 에로그온하고작업하려는사용자를선택한다. 역주5 그런다음페이지아랫부분의 Manage this user s bookmarks( 이사용자의즐겨찾기관리 ) 링크를클릭한다. 그러면그림 2-9와같이즐겨찾기를정의할수있는인터페이스가나타난다. 5) 그림 2-9 세가지즐겨찾기를보여주는 Edit Bookmarks( 즐겨찾기편집 ) 화면 역주 5 services.multimobiledevelopment.com 에로그온한다음, Manage users( 사용자관리 ) 링크를클릭하면앞에서 만든사용자가표시된다. 이사용자명링크를클릭하면해당사용자를편집할수있는페이지가표시되는데, 이 페이지아랫부분에 Manage this user s bookmarks( 이사용자의즐겨찾기관리 ) 링크가있다.
18 CHAPTER 2 Six Bookmarks 의서버서비스 즐겨찾기를몇가지입력하고 Save Changes( 변경내용저장 ) 버튼을클릭한다. OData 로작업하기 자, 이제 Bookmarks 서비스를사용해보자. 테스트용도구를다시사용할텐데, 그러면토큰이또필요하다. 지금토큰이없다면앞내용에따라다시토큰을얻는다. 테스트용도구에서 Bookmarks OData 링크를클릭하면다음과같은 URL 결과를다시얻게된다. http://services.multimobiledevelopment.com/services/bookmarks.svc/ Send Request 버튼을클릭하면그림 2-10과같은결과를확인할수있다. 여기서유의해야할점은이테스트용도구가계속해서특별한헤더를전송한다는것이다. 만일이헤더가없거나정확하지않으면, 서비스호출은거부된다. OData 표준에서는데이터가 ATOM 포맷이나 JSON 포맷으로리턴된다. JSON 포맷은웹페이지의 Ajax 호출과작업할때사용되는것이일반적이라서여기서는 ATOM 포맷이적절한데, 중요한것은 OData 가공개표준을바탕으로작성되었다는점이다. 특히마이크로소프트는핵심데이터프로토콜로서 OData 가자리를잡아간다고보고, 완전한패키지로구현한닷넷 3.5 SP1을시작으로 OData 를애저 (Azure) 플랫폼에서지원한다. 그림 2-1 0 Bookmarks OData 서비스에대해성공한호출
Bookmarks 서비스 19 이결과화면에서 Bookmarks 서비스가 Bookmark 라는데이터타입을반환한다는것을알수 있다 (XML 의 atom:title 요소로확인할수있다 ). 다시테스트용도구를사용할텐데, 다음주소를 URL 입력란에복사해서붙여넣기하면앞에서작성한즐겨찾기에해당하는내용이출력된다. http://services.multimobiledevelopment.com/services/bookmarks.svc/bookmark 이제부터는스크린샷이아닌리스트형태로 XML 출력결과를나타낼것이다. 그래야이해하기 편할것이다. 다음의 XML 코드에서는이호출로부터반환된 6 가지즐겨찾기를확인할수있다. 물론여러분이 직접작성한즐겨찾기가있다면다음출력결과와달라질것이다. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <feed xml:base="http://services. multimobiledevelopment.com/services/bookmarks.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/atom"> <title type="text">bookmark</title> <id>http://services. multimobiledevelopment.com/services/bookmarks.svc/bookmark</id> <updated>2010-04-18t10:54:32z</updated> <link rel="self" title="bookmark" href="bookmark" /> <entry> <id>http://services. multimobiledevelopment.com/services/bookmarks.svc/bookmark (1002)</id> <title type="text"></title> <updated>2010-04-18t10:54:32z</updated> <author> <name /> </author> <link rel="edit" title="bookmark" href="bookmark(1002)" /> <category term="amxmobile.services.bookmark" scheme="http://schemas.microsoft.com/ ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:bookmarkid m:type="edm.int32">1002</d:bookmarkid> <d:userid m:type="edm.int32">1001</d:userid> <d:name>.net 247</d:Name> <d:url>http://www.dotnet247.com/</d:url> <d:ordinal m:type="edm.int32">1</d:ordinal> </m:properties> </content> </entry> <entry> <id>http://services. multimobiledevelopment.com/services/bookmarks.svc/bookmark(1001)</id>
20 CHAPTER 2 Six Bookmarks 의서버서비스 <title type="text"></title> <updated>2010-04-18t10:54:32z</updated> <author> <name /> </author> <link rel="edit" title="bookmark" href="bookmark(1001)" /> <category term="amxmobile.services.bookmark" scheme= "http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:bookmarkid m:type="edm.int32">1001</d:bookmarkid> <d:userid m:type="edm.int32">1001</d:userid> <d:name>google</d:name> <d:url>http://www.google.co.uk/</d:url> <d:ordinal m:type="edm.int32">0</d:ordinal> </m:properties> </content> </entry> <entry> <id>http://services.multimobiledevelopment.com/services/bookmarks.svc/bookmark(1003)</id> <title type="text"></title> <updated>2010-04-18t10:54:32z</updated> <author> <name /> </author> <link rel="edit" title="bookmark" href="bookmark(1003)" /> <category term="amxmobile.services.bookmark" scheme= "http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:bookmarkid m:type="edm.int32">1003</d:bookmarkid> <d:userid m:type="edm.int32">1001</d:userid> <d:name>topaz Filer</d:Name> <d:url>http://www.topazfiler.com/</d:url> <d:ordinal m:type="edm.int32">2</d:ordinal> </m:properties> </content> </entry> </feed> ATOM 포맷이명료하기때문에데이터셋이낯설어도그포맷을이해하기는매우쉽다. 각 feed/entry 요소에는데이터항목 ( 이제부터는앞으로사용하게될객체의관계매핑구조에대해일관된 명명법을유지하는차원에서 엔터티 라는용어를사용할것이다 ) 이하나포함되어있다. feed/entry 요 소안에있는 m:properties 요소에데이터가들어간다 ( 즐겨찾기를저장하는데사용되는테이블과그
Bookmarks 서비스 21 구조가 1:1 로대응된다 ). 여기에는흥미로운요소로 ID 가있는데, ID 는각항목에액세스하는데사용되는 URL 을제공한 다. 그러나서비스가데이터를반환하게하려면특별한헤더를전송해야한다는점을기억해야 한다. 즐겨찾기집합에들어있는어떤항목의 ID 를골라다시요청하면이에해당하는 XML 코드를 얻을수있다. 예를들어 Topaz Filer 즐겨찾기의 ID 인아래주소를 URL 입력란에입력해보자. http://services.multimobiledevelopment.com/services/bookmarks.svc/bookmark(1096) 다음은이즐겨찾기하나에만해당하는 XML 코드다. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <entry xml:base="http://services.multimobiledevelopment.com/services/bookmarks.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/atom"> <id>http://services.multimobiledevelopment.com/services/bookmarks.svc/bookmark(1003) </id> <title type="text"></title> <updated>2010-04-18t10:55:13z</updated> <author> <name /> </author> <link rel="edit" title="bookmark" href="bookmark(1003)" /> <category term="amxmobile.services.bookmark" scheme= "http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:bookmarkid m:type="edm.int32">1003</d:bookmarkid> <d:userid m:type="edm.int32">1001</d:userid> <d:name>topaz Filer</d:Name> <d:url>http://www.topazfiler.com/</d:url> <d:ordinal m:type="edm.int32">2</d:ordinal> </m:properties> </content> </entry>
22 CHAPTER 2 Six Bookmarks 의서버서비스 OData 쿼리 OData 표준에서는여러가지많은작업을제공한다. 그중하나는 $metadata 지시자로서, 이지시자는서비스가반환하는데이터포맷을결정하기 위한깔끔한방법이다. 예를들어다음요청을하면데이터구조를확인할수있다. http://services.multimobiledevelopment.com/services/bookmarks.svc/$metadata <edmx:edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"> <edmx:dataservices xmlns:m="http://schemas.microsoft.com/ado/2007/ 08/dataservices/metadata" m:dataserviceversion="1.0"> <Schema Namespace="AmxMobile.Services" xmlns:d= "http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m= "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns= "http://schemas.microsoft.com/ado/2007/05/edm"> <EntityType Name="Bookmark"> <Key> <PropertyRef Name="BookmarkId" /> </Key> <Property Name="BookmarkId" Type="Edm.Int32" Nullable="false" /> <Property Name="UserId" Type="Edm.Int32" Nullable="false" /> <Property Name="Name" Type="Edm.String" Nullable="true" /> <Property Name="Url" Type="Edm.String" Nullable="true" /> <Property Name="Ordinal" Type="Edm.Int32" Nullable="false" /> </EntityType> <EntityContainer Name="BookmarkCollection" m:isdefaultentitycontainer="true"> <EntitySet Name="Bookmark" EntityType="AmxMobile.Services.Bookmark" /> </EntityContainer> </Schema> </edmx:dataservices> </edmx:edmx> 또한가지방식은데이터를제한하기위한쿼리를실행하는능력이다. 예를들어이름이 Google 인모든즐겨찾기를반환하려면다음처럼요청을한다. http://services.multimobiledevelopment.com/services/bookmarks.svc/ Bookmark?$filter=Name eq 'google' 유의할점은이곳이쿼리에추가제한조건이더해지는곳이어서, 서비스가현재작업하고있는 즐겨찾기집합에는로그인한사용자의즐겨찾기만이포함된다는것이다. 이과정은나중에자 세하게다룰것이다.
정리 23 이책에서우리는어떤사용자의모든즐겨찾기를검색하고변경내용을알리는데이서비스를이용하고있다. Error! Hyperlink reference not valid( 오류! 하이퍼링크참조가유효하지않습니다 ) 라는오류에아랑곳하지않고마음껏 OData 를경험하길바란다. www.odata.org 웹사이트에는프로토콜에관한정보가매우많이실려있고, Six Bookmarks 서비스보다더욱흥미롭고완전한기능을갖춘데이터셋참조또한포함되어있다. 유용한 OData 서비스는 www.odata.org/ producedrs/ 에서확인할수있다. OData 를사용하여업데이트알리기 앞서설명한대로서버쪽데이터를업데이트하기위해 OData 를사용할텐데, 웹브라우저를 사용하여이과정을보여주기가녹록치않다. 아쉽지만다른장에서다루기로하겠다. 로그온한사용자에게데이터를제한하기 서비스의안을들여다보면 IIS가요청을받을때, ASP.NET, ADO.NET, WCF(Windows Communication Foundation) 는함께동작하며요청을처리한다. 그래서 SQL 구문이만들어지고이것이 SQL 서버로전달된다. SQL 구문이실행되기바로전에추가제한조건이더해져사용자 ID와로그온한사용자가동일한경우에만즐겨찾기가반환된다. 따라서 WCF가 select * from bookmarks 구문을실행하려고하면추가제한조건이슬며시더해져실제로는 select * from bookmarks where userid=27 이실행된다 ( 사용자 ID는상황에따라바뀐다 ). 이과정을정리하면먼저 URL 재작성을사용하여토큰을추출하고, HttpContext.Current.Items 컬렉션에이토큰을저장한다음, 적당한시간에역참조하고, 최종적으로 SQL 쿼리에추가제한조건을첨부한다. 서버소스코드패키지를다운로드하면이코드를확인할수있지만, 앞에서말한대로여러분의서버가이기능을필요로하는경우는별로없을것이다. 정리 이장에서우리는클라우드서비스와첫만남을가졌고, 앞으로작성할클라이언트애플리케이션에데이터와기능을제공하는과정을살펴보았다. 그리고 API 서비스와 Users 서비스의호출방법을살펴보았으며, Bookmarks OData 서비스를사용하여데이터를요청하는방법도들여다보았다. 다음장에서는 Six Bookmarks 애플리케이션의아키텍처와스펙을살펴보겠다.