본문 바로가기

ActionScript/AS3.0

네이버 openAPI와 XMLConnector 컴포넌트를 이용한 책검색

출처 What you see is what you get | 아킨토스
원문 http://blog.naver.com/etwas0227/60030846496
 


  양주일

양주일


목차

작성일:
2006년 5월 10일

소개

요즘 웹2.0이란 새로운 흐름과 함께 국내외에서 개방형 API를 제공하는 사이트들이 증가하고 있습니다. 개방형 API를 사용하면 자신의 아이디어를 보다 다양한 기술들과 접목시켜 제작하는 것이 가능하며 여기에 플래시의 XML 처리 기술과 UI 컴포넌트들을 함께 사용한다면 더욱 다양한 사용자 경험을 창조해 낼 수 있습니다.

최근 공개된 네이버 오픈 API와 간편하게 XML 데이터를 연동할 수 있는 플래시의 XMLConnector 컴포넌트를 사용하여 간단하면서도 멋진 책 검색 플래시 어플리케이션을 제작하는 방법에 대해 살펴봅니다.  

요구사항

본 학습 과정을 수행하려면 다음과 같은 소프트웨어와 파일이 필요합니다.

Macromedia Flash Professional 8
시험버전
구입
자습서 및 샘플 파일
OpenAPI.zip (ZIP, 1.39MB)
사전지식
XML과 스키마, 컴포넌트에 대한 기본 지식


저자 소개



양주일은 현재 NHN UX 디자인센터의 UI 이노베이션팀 팀장입니다. 네이버에서 플래시를 활용한 검색컨텐츠 제작 및 AJAX를 이용하여 향상된 사용자 경험을 창조하기 위해 노력하고 있습니다. 플래시 커뮤니티 feople.com을 운영했었고, 현재는 플래시 관련 블로그 asoop.com을 운영중입니다. 다양한 플래시 제작 경험을 바탕으로 플래시 액션스크립트 2.0 무작정 따라하기를 집필, 콜린 무크의 액션스크립트 2.0을 번역하는 등 활발한 집필활동을 진행하고 있습니다.

------------------------------------------------------------------------------------




오픈API에 대한 이해

요즘 들어 인터넷 산업 전반에 걸쳐 웹2.0이란 용어가 화두로 등장하고 있습니다. 혹자는 이와 같은 흐름이 단지 유행에 불과하다며 평가 절하하기도 하지만, 대중의 지지를 얻은 새로운 신주류임은 틀림이 없습니다. 웹2.0에 대해 간략히 정의하면 앞으로의 웹은 대중의 참여가 절대적이며, 응용프로그램을 대체할 수 있는 플랫폼으로써의 웹이 점차 자리를 잡아가고 있다고 말할 수 있습니다.

웹2.0과 더불어 등장하는 새로운 시도들 중에는 기존 서비스 업체들이 자사가 보유하고 있는 데이터를 공개하고 이를 다양한 서비스로 확장할 수 있도록 제공하는 개방형 API가 있습니다. 이미 외국의 많은 업체들은 개방형 API를 제공하고 있으며, 이를 이용하여 인터넷 유저들에 의해 제작된 많은 사이트들이 생성되고 있습니다. 대표적인 개방형 API를 예로 들면 다음과 같습니다.

다음은 이들 사이트의 API를 활용하여 새로운 서비스를 만들어 낸 사이트들의 목록입니다.

이들 사이트를 살펴보면 알 수 있듯이 그 동안 각 기업의 내부에 갇혀 존재하던 데이터가 공개됨에 따라서 다양한 부가가치와 사용자 경험을 창출할 수 있는 기술과 서비스가 대거 등장하게 되었습니다. 즉, 인터넷을 이용하는 대중의 아이디어와 기업의 유관 기술을 접목하여 새로운 서비스를 창조해 낼 수가 있는 것입니다.

국내에서도 포털을 중심으로 많은 사이트들이 개방형 API의 도입을 서두르고 있으며 그 중 네이버가 처음으로 오픈API(http://openapi.naver.com)를 제공하기 시작 했습니다. 이들 API를 사용하면 '그림 1, 2'와 같이 네이버 검색의 모습을 새롭게 재구성해 볼 수도 있으며, 더욱 다양한 서비스를 자신의 아이디어와 접목시켜 볼 수도 있습니다. 

오픈 API를 활용한 네이버 검색의 재구성

그림 1. 오픈 API를 활용한 네이버 검색의 재구성(http://www.asoop.com/lab/naver/)

재구성된 네이버 검색 결과 페이지

그림 2. 재구성된 네이버 검색 결과 페이지

앞으로 이들 개방형 API를 활용한 많은 사이트들이 등장하기를 기대하며, 개방형 API와 플래시를 활용하는 방법에 대해 살펴보도록 하겠습니다.



---------------------------------------------------------------------------------




네이버 오픈 API 사용 등록

네이버 오픈 API를 사용하여 아래 '그림 3'과 같은 책 검색 어플리케이션을 제작해 볼 것입니다.

플래시 책 검색

그림 3. 플래시 책 검색 (http://www.asoop.com/lab/findbook/)

오픈 API를 사용하기 위해서는 우선 사용자 키를 발급받아야 합니다. 대부분의 개방형 API를 제공하는 사이트들은 사용자 키를 요구하게 되는데, 이것은 API 서비스를 이용하기 위한 작은 수고가 필요한 과정입니다. 

  1. 네이버 Open API 사이트에 접속합니다.
    http://openapi.naver.com

    네이버 오픈 API 사이트

    그림 4. 네이버 오픈 API 사이트

  2. 왼쪽 하단의 'API 이용등록/수정' 링크를 클릭합니다. 이때 로그인이 안된 상태라면 로그인 과정을 거칩니다. 네이버 아이디로 로그인 하셔야 합니다.
  3. API 이용등록 페이지가 나타나면, 자신의 e-mail을 확인하고 연락처를 입력합니다.
  4. 사용예상 API에서 원하는 검색을 선택합니다. 일종의 설문 조사 과정이며, 선택하지 않았다고 해서 사용을 못하는 것은 아닙니다.
  5. 사용용도 입력란에 어떤 것을 만들지 예상을 하셔서 작성합니다.
  6. 모든 입력이 완료되면 '위 약관에 동의합니다'를 체크한 후 신청을 완료합니다.

    API 이용 등록 화면

    그림 5. API 이용 등록 화면

  7. 신청이 완료되면 '그림 6'에서와 같이 알파벳과 숫자로 구성된 사용자 키가 발급됩니다. 이 키를 복사해서 저장해두시기 바랍니다. 만일 키를 잊었다면 다시 API 이용등록 페이지에서 확인할 수 있습니다.

    사용자 키 발급 화면

    그림 6. 사용자 키 발급 화면


------------------------------------------------------------------------------------




XMLConnector 컴포넌트를 이용한 데이터 연결

이제 오픈 API와 플래시의 XMLConnector 컴포넌트를 이용하여 데이터 연동방법을 살펴 볼 차례입니다. 사용할 API는 네이버 책 검색 API이며, 이에 대한 자세한 API 사용방법은 네이버 오픈 API 페이지를 참고하십시오.

우선 '그림 7'과 같은 화면을 제작합니다.

오픈 API를 이용하여 제작해볼 어플리케이션 화면 구성

그림 7. 오픈 API를 이용하여 제작해볼 어플리케이션 화면 구성

  1. 가로 800 세로 400 픽셀의 새로운 플래시 파일을 생성합니다.
  2. [Window]> Components 패널을 클릭한 다음 UI 컴포넌트를 선택합니다.
  3. TextInput 컴포넌트를 화면 상단에 배치한 다음 속성창(Properties)에서 인스턴스 네임을 input_txt 라고 부여합니다.
  4. 다음으로 Button 컴포넌트를 화면에 배치하고 인스턴스 네임을 search_btn 이라고 설정합니다.
  5. 계속해서 DataGrid 컴포넌트를 viewForm 이란 인스턴스 네임을 사용하여 배치하고 마지막으로 XMLConnector 컴포넌트를 배치한 후 XMLCon 이란 인스턴스 네임을 부여합니다(XMLConnector 컴포넌트는 컴포넌트 패널에서 UI 컴포넌트가 아닌 Data 컴포넌트에 들어있습니다).

화면 구성이 끝나면 XML의 구조를 정의하는 스키마를 설정할 차례입니다.

팁! 스키마(Schema)는 XML의 골격을 나타내는 것으로 노드에 사용된 태그 구조를 의미합니다.

  1. 우선 불러올 XML 샘플을 저장해야 합니다. http://openapi.naver.com/sample/book.xml 파일을 자신의 하드디스크에 저장합니다. 이 파일은 XMLConnector 컴포넌트의 스키마 파일로 사용할 것입니다. 2.
  2. XMLConnector 컴포넌트(XMLCon)를 선택합니다. 3.
  3. [Window] > Component Inspector를 클릭한 다음 Schema 탭을 선택합니다. 4.
  4. Schema 탭에서 results를 클릭한 다음 '그림 8'과 같이 스키마 추가 버튼을 선택합니다.

    스키마 추가 과정

    그림 8. 스키마 추가 과정

  5. 파일 탐색기가 나타나면 과정 1번에서 저장한 XML 파일을 선택합니다.
  6. 스키마가 추가되면 [그림 9]와 같이 XML 파일을 구조가 화면에 나타납니다.

    XML 스키마

    그림 9. XML 스키마


 

다음으로 데이터바인딩을 설정할 차례입니다. 데이터바인딩은 컴포넌트들 사이의 상호 데이터 입출력을 위한 설정으로 XMLConnector 컴포넌트를 통해 받은 데이터를 DataGrid 컴포넌트로 연결시키는 작업을 할 것입니다.

  1. XMLConnector를 선택한 후 Component Inspector에서 Bindings 탭을 클릭합니다.
  2. Add Binding 버튼(+)을 클릭합니다.
  3. results 노드를 따라 내려가다가 item : Array 라고 적혀있는 부분을 선택합니다(그림 9 참고). 이것은 검색결과에 해당하는 부분으로 검색 결과는 배열로 전달 됩니다.

    바인딩 항목 추가

    그림 10. 바인딩 항목 추가

  4. OK 버튼을 누르면 results.rss.channel.item 이라는 바인딩 항목이 추가됩니다.
  5. results.rss.channel.item을 선택한 상태에서 Bindings 탭 하단을 살펴보면 데이터를 어느 곳으로 연결시킬 지를 설정하는 항목들이 나타납니다. 여기서 direction을 out 또는 in/out 으로 설정합니다. direction은 데이터가 이동하는 방향을 가리키며, XMLConnector에서 DataGrid 쪽으로 보낼 예정이므로 out 방향이 있어야 합니다(out 또는 in/out).
  6. 마지막으로 bound to 항목을 더블클릭하여 데이터를 보낼 컴포넌트와 스키마 위치를 선택합니다. [그림 11]과 같이 컴포넌트는 DataGrid(인스턴스 viewForm)를 선택하고, 스키마는 dataProvider로 설정합니다. dataProvider는 DataGrid 컴포넌트에서 데이터를 주고받는 역할을 담당하는 배열입니다.

    바인딩 설정

    그림 11. 바인딩 설정

팁! 네이버 오픈API는 RSS란 XML 문서구조로 되어있습니다. RSS에 대해서 문서 구조를 파악하고 있다면 보다 상세히 데이터를 살펴볼 수 있습니다. RSS에 대한 자료는 인터넷에서 검색해 보시면 관련 자료들을 많이 찾을 수 있습니다.

이제 모든 제작이 거의 끝났습니다. 마지막으로 다음과 같이 첫 번째 프레임에 액션스크립트를 입력합니다(완성된 파일 openapi.fla 을 참고하십시오).

var key:String = "사용자 키를 이곳에 입력합니다.";

function searchBook(q:String){
	q = escape(q);	// 검색어는 url 인코딩으로 처리해야 합니다. 
	xmlCon.URL = "http://openapi.naver.com/search?key="+key
+"&query="+q+"&display=10&start=1&target=book&sort=sim";
	xmlCon.trigger();
	viewForm.text = "";
}

search_btn.onPress = function(){
	searchBook(input_txt.text);
}
		

key 변수에는 앞에서 발급받은 자신의 사용자 키를 복사해서 넣어야 합니다. xmlCon은 XMLConnector 컴포넌트의 인스턴스 네임이며 검색을 실행하는 순간 오픈 API의 책검색 URL을 생성하여 XMLConnector로 전달합니다. trigger() 메쏘드는 XMLConnector 컴포넌트에 설정된 URL 속성으로부터 XML 데이터를 받아오도록 하는 명령입니다.

테스트 무비를 실행한 다음 검색어를 input_txt에 입력하고 [검색] 버튼을 누르면 네이버 오픈 API 책검색에서 해당 검색 내용을 받아와서 화면에 나타냅니다.

완성된 검색 결과 화면

그림 12. 완성된 검색 결과 화면

팁! 검색어 입력창에서 단어를 입력한 후 엔터키를 누를때 검색이 실행되도록 제작하려면 앞에서 입력한 액션스크립트에 추가로 다음과 같이 작성하면 됩니다.

var keyListener:Object = new Object();
keyListener.onKeyDown = function(){
	if(Key.getCode() == Key.ENTER 
&& Selection.getFocus().indexOf("input_txt") > 0){
		searchBook(input_txt.text);
	}	
}
Key.addListener(keyListener);



----------------------------------------------------------------------------------




DataGrid 컴포넌트를 이용한 데이터 재정의

앞에서 만든 파일을 응용해서 새롭게 제작할 어플리케이션의 구조는 '그림 13'과 같습니다(참고 파일 openapi2.fla).

새로운 어플리케이션 화면 구성

그림 13. 새로운 어플리케이션 화면 구성

앞에서 제작해 본 구성과 다른 부분은 DataGrid 컴포넌트를 검색 결과 리스트로 사용하고(인스턴스네임 listForm) 검색 결과에서 선택된 아이템의 상세한 정보를 TextArea 컴포넌트를 사용하여 출력하게 됩니다(인스턴스네임 viewForm). 또한 검색 결과 수를 표시하기 위해 Label 컴포넌트(인스턴스네임 total)를 검색 버튼 바로 옆에 사용하였습니다. 또한 화면에 보이지는 않지만 검색 결과가 없는 경우 안내창을 띄우기 위해 Alert 컴포넌트를 라이브러리에 추가해야 합니다. 컴포넌트 패널에서 Alert 컴포넌트를 스테이지로 드래그 한 후 삭제하면 라이브러리에 남아있게 됩니다.

앞에서는 검색 결과를 모두 DataGrid 컴포넌트로 출력하였으나 이번에는 책의 제목, 저자, ISBN 정보만을 추출하여 리스트에 출력할 계획입니다.

데이터 재정의

데이터바인딩에 의해 DataGrid로 전달된 데이터의 일부만을 사용하려면 데이터를 새롭게 정의해야만 합니다. 데이터에 대한 정의는 바인딩 설정항목에서 변경이 가능합니다.

데이터 포매터 설정

그림 14. 데이터 포매터 설정

  1. XMLConnector 컴포넌트를 선택한 다음 Component Inspector를 불러옵니다.
  2. Bindings 탭에서 results.rss.channel.item 항목을 선택합니다.
  3. 하단에서 formatter 옆 Value를 설정하는 부분을 더블클릭하여 Rearrange Fields를 선택합니다. 이것은 전달 받은 데이터를 새롭게 재구성하는 설정입니다('그림 14' 참고).
  4. formatter options에서 Value를 더블클릭하여 다음과 같이 입력합니다. <> 로 묶인 것은 XML 문서의 노드 이름이며 이들 노드에 설정된 값을 새로운 이름으로 재정의하는 과정입니다. 따라서 TITLE에는 책의 제목(<title>)의 값이 저장되며, IMG에는 이미지의 URL인 노드의 값이 저장됩니다.
    TITLE='<title>';AUTHOR='<author>';ISBN='<isbn>';
    PRICE='<price>';DESC='<description>';IMG='<imageurl>';
    LINK='<link>';PUB='<publisher>'
  5. 마지막으로 새로운 바인딩 추가 버튼을 눌러(+) results.rss.channel.total 값을 Label 컴포넌트(인스턴스네임 total)로 연결합니다.

Label 컴포넌트로 바인딩 설정

그림 15. Label 컴포넌트로 바인딩 설정

바인딩 설정이 끝나면 액션스크립트를 입력할 차례입니다. 여기서 사용한 액션스크립트는 앞에서 제작해본 방법의 연장선상에 있습니다. 자세한 코드 사용법은 주석을 참고하시기 바랍니다.

import mx.controls.Alert;		
// 검색결과가 없을때 안내창을 띄우기 위해 Alert 컴포넌트를 사용합니다.
total.color = 0xFFFFFF;	// 레이블 컴포넌트의 글자색상을 흰색으로 설정합니다. 
total.text = "";		// 레이블 컴포넌트의 텍스트를 없앱니다(초기화). 

var key:String = "사용자 키를 이곳에 입력합니다.";
function searchBook(q:String){
	q = escape(q);
	xmlCon.URL = "http://openapi.naver.com/search?key="+key
                      +"&query="+q+"&display=10&start=1&target=book&sort=sim";

	xmlCon.trigger();
	viewForm.text = "";
}

listForm.columnNames = ["TITLE", "AUTHOR", "ISBN"];
/* DataGrid 상단에 레이블을 설정합니다.
아래와 같이 입력하는 것과 동일한 방법입니다.
listForm.addColumn("TITLE");
listForm.addColumn("AUTHOR");
listForm.addColumn("ISBN");
*/

listForm.getColumnAt(0).width = 180;
listForm.getColumnAt(1).width = 120;
listForm.getColumnAt(2).width = 100;
// DataGrid의 각 컬럼의 가로 길이를 설정합니다. 

listForm.vScrollPolicy = "auto";
listForm.getColumnAt(0).cellRenderer = "HTMLCell";
listForm.getColumnAt(1).cellRenderer = "HTMLCell";
// DataGrid의 첫번째와 두번째 컬럼에 HTML 출력이 가능하도록 
// HTMLCell 클래스를 사용합니다. 

gridListener = new Object();
// DataGrid의 한줄을 선택하면 상세한 책의 정보를 TextArea 컴포넌트로 출력합니다.
   gridListener.cellPress = function(evt:Object){
   var obj = evt.target.dataProvider.getItemAt(evt.target.selectedIndex);
   viewForm.text = "<p><font size='14'><u>"+obj.TITLE+"</u></font></p>"
  +"<img src='" + obj.IMG +"' align='right'>"
  + "저자 : " + obj.AUTHOR
  + "<br>출판사 : " + obj.PUB
  + "<br>ISBN : " + obj.ISBN
  + "<br>가격 : " + obj.PRICE
  + "<br><br>" + obj.DESC
  + "<br><br>[<u><a href='"+obj.LINK+"' target='_blank'>자세히보기</a></u>]";
  }


var xmlListener:Object = new Object();
xmlListener.result = function(evt:Object) {
	if(total.text == ""){
		Alert.show("검색결과가 없습니다", "안내", Alert.OK);
		total.text = 0;
		listForm.removeEventListener("cellPress", gridListener);
}else{
		listForm.addEventListener("cellPress", gridListener);
		// 검색결과가 있을때만 상세 정보를 출력합니다. 
	}
	total.text += "건의 책이 검색되었습니다.";
};

xmlCon.addEventListener("result", xmlListener);

search_btn.onPress = function(){
	searchBook(input_txt.text);
}

var keyListener:Object = new Object();
keyListener.onKeyDown = function(){
	if(Key.getCode() == Key.ENTER && Selection.getFocus().indexOf("input_txt") > 0){
		searchBook(input_txt.text);
	}	
}
Key.addListener(keyListener);
input_txt.text = "flash";	// 기본 검색어를 'flash'로 설정하여 출력합니다.
searchBook(input_txt.text);

코드 중에서 유심히 살펴볼 곳은 cellRenerer와 cellPress를 설정하는 부분입니다.

listForm.getColumnAt(0).cellRenderer = "HTMLCell";
listForm.getColumnAt(1).cellRenderer = "HTMLCell";

cellRenderer는 DataGrid의 각 행(column)의 컨텐츠를 어떻게 출력할 것이냐에 대한 방법을 설정합니다. HTMLCell이라고 정의한 것은 HTMLCell.as 클래스 파일로써 다음과 같습니다.

HTMLCell.as 파일

class HTMLCell extends mx.core.UIComponent
{
	private var htmlLabel; 	
	private var owner; 	
	private var listOwner; 	
	
	private static var PREFERRED_HEIGHT_OFFSET = 4;
	private static var PREFERRED_WIDTH = 100;
	private var startDepth:Number = 1;

	public function HTMLCell(){
	}

	public function createChildren():Void{
		var c = htmlLabel = this.createLabel("htmlLabel", startDepth);
		c.styleName = listOwner;
		c.selectable = false;
		c.tabEnabled = false;
		c.background = false;
		c.border = false;
		c.html = true;
		c.wordWrap = true;
		c.autoSize = true;
	}

	public function size():Void{
		var c = htmlLabel;
		c.setSize(__width, __height);
	}

	public function getPreferredHeight():Number{
		return owner.__height - PREFERRED_HEIGHT_OFFSET;
	}

	public function setValue(input:String, item:Object, selected:Boolean):Void{
		if (item==undefined){
			htmlLabel.text._visible = false;
		}
		htmlLabel.htmlText = input;
	}
}

기본적으로 DataGrid는 텍스트 출력만을 담당하며 HTML 태그를 화면에 그대로 출력합니다. 하지만 오픈API를 활용한 검색결과는 검색어를 '<b>플래시</b>'와 같이 태그를 사용하여 굵은 글씨로 표시합니다. 따라서 책 제목, 저자명에 사용하는 행을 구해 낸 다음(listForm.getColumnAt(0)와 같이) 여기에 HTML 출력이 가능하도록 cellRenderer를 설정한 것입니다. 이와 같이 cellRenderer를 제작하는 자세한 방법은 다음 문서를 참고하시기 바랍니다.

www.adobe.com/support/documentation/en/flash/fl8/samples.html#component_samples

gridListener는 DataGrid에서 선택한 항목의 상세정보를 출력하는 역할을 담당합니다. cellPress는 DataGrid의 이벤트로써 특정 행을 선택했을 때 동작합니다. 따라서 검색결과가 있을 때, 다음과 같은 addEventListener() 메쏘드를 사용하여, 앞에서 Rearrange Fields 를 통해 재정의한 데이터를 가공하여 TextArea(viewForm)으로 전달하는 역할을 합니다.

listForm.addEventListener("cellPress", gridListener);

데이터가 없을 때는 removeEventListenr() 메쏘드를 사용하여 이벤트를 삭제합니다. 왜냐하면 검색결과가 없을 때에도 DataGrid를 선택할 수 있도록 한다면 undefined라는 문자열이 TextArea에 출력되기 때문입니다.

지금까지 XMLConnector 컴포넌트와 네이버 오픈 API를 연동하여 플래시 책 검색 어플리케이션을 제작 해보았습니다. 실제로 XML과 데이터 연동 제작방법은 XML 클래스와 XMLNode 클래스를 사용하여 많이 제작합니다. 왜냐하면 그만큼 XML과 XMLNode 클래스를 사용하면 보다 손쉽고 다양하게 제어하는 것이 가능하기 때문입니다. 그러나 간단한 어플리케이션의 경우 앞에서 제작해 본 방법처럼 XMLConnector 컴포넌트와 다른 UI 컴포넌트들을 사용하는 것만으로도 손쉽게 제작할 수 있습니다.



----------------------------------------------------------------------------------------



출처: http://www.adobe.com/kr/devnet/flash/articles/naver_openapi.html