HTTPService를 이용하면 XML, JSON등의 형식으로 데이터를 송신 및 수신할 수 있다.
그런데 이번에 다음 책 검색API를 이용하여 웹 사이트를 만들려고 했었는데, 이 때 큰 문제가 있었다.

보통 액션스크립트를 이용해서 받아온 xml데이터를 조작해 줄 필요가 있을 것이다.
그러면 for문이나 for each문을 이용해서 하나하나의 값을 조작해줘야 하는데, xml에 들어있는 값이 여러개일 때에는 문제가 되지 않는데 1개의 값만 갖고 있을 때 문제가 발생한다.

받아온 xml의 형식은 아래 그림과 같다고 하고 예를 살펴보자.

root는 channel이고 그 밑에 Item의 총 개수를 나타내는 totalCount가 있고, Item이 0개 이상 존재하게 된다. 각 아이템마다 title과 imageSrc를 가지게 된다.

이런 형식의 데이터를 받아온다고 했을 때, 보통은 다음과 같은 방식으로 HTTPService의 resultHandler를 코딩하게 될 것이다.
private function resultHandler(event : ResultEvent) : void {
	if(event.result.channel.totalCount == 0) {
		Alert.show("표시할 아이템이 없습니다.");
		return;
	}

	for each(var item : Object in event.result.channel.item) {
		//item.title 처리
		//item.imageSrc 처리
	}
}

이런식으로 코딩을 하게 되면 평소에는 잘 동작하는 듯 보인다. 그런데 그 결과를 잘 살펴보면 잘 못 동작하고 있다는 것을 알 수 있다.
바로 Item이 1개일 경우이다. Item이 1개일 경우에는 for each문을 수행하지 않는다. 그래서 아무런 결과 값도 처리할 수 없게 된다. 이러한 문제는 만들려는 프로그램의 종류에 따라서는 심각한 문제가 될 수 있다.

그래서 열심히 구글링한 결과 다음과 같이 코딩하면 된다는 것을 알았다.
private function resultHandler(event : ResultEvent) : void {
	if(event.result.channel.totalCount == 0) {
		Alert.show("표시할 아이템이 없습니다.");
		return;
	}
	
	var results : ArrayCollection;
	
	if(event.result.channel.item == null) {
		Alert.show("데이터가 없습니다.");
		return;
	} else if(event.result.channel.item is ObjectProxy) {
		results = new ArrayCollection([event.result.channel.item]);
	} else {
		results = event.result.channel.item as ArrayCollection;
	}
	
	for each(var item : Object in result) {
		//item.title 처리
		//item.imageSrc 처리
	}
}

신고
Posted by Code-Moon

댓글을 달아 주세요

  1. BlogIcon pooha302 2010.03.11 17:02 신고 Address Modify/Delete Reply

    XML의 데이터 구조에 따라 for each로 사용 가능한지 판단해서 적절히 사용할 수 있도록 해야지.
    나는 짜증나면 for문으로 전부 일일이 파싱해서 처리하는데 ㅋㅋ
    근데 뭐하는데 액션스크립트를 사용하노??

    • BlogIcon Code-Moon 2010.03.16 11:09 신고 Address Modify/Delete

      원래 for each는 1개일때 안되요??

    • BlogIcon Code-Moon 2010.03.16 11:10 신고 Address Modify/Delete

      아, 그리고 중학교 때 플래시를 썼었는데,ㅎ 그동안 버려두고 있었거든요,ㅎ 그래서 제가 알고있는 as가 2.0 수준이었는데,ㅎ
      이번에 플렉스도 해볼겸 해서 as3.0으로 매쉬업 해볼려고했죠.ㅎ

플렉스에서 애니메이션을 만드는 방법은 2가지가 있다.

1. 먼저 첫번째는 enterFrame이벤트를 이용하는 것이다.
이는 원래 플래시에서 사용하던 방식인데, 프레임 개념을 사용해서 애니메이션을 만드는 것이다.

enterFrame이벤트를 사용하기 위해서는 이벤트 리스너를 등록시켜줘야 한다.

addEventListener(Event.ENTER_FRAME, onEnterFrame);

이렇게 해주면 enterFrame에 대한 이벤트 리스너가 등록된 것이다.
두번째 인자인 onEnterFrame은 매 프레임마다 호출되는 함수이다.
그러면 이제 우리가 해야할 일은 onEnterFrame함수를 작성하는 것이다.

private function onEnterFrame(event : Event) : void  {
  //매 프레임마다 해야할 작업을 작성한다.
}

그러면 이제 마우스를 따라 부드럽게 움직이는 이미지를 만들어보자.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" mouseMove="onMouseMove(event)" width = "400" height = "400" verticalScrollPolicy="off" horizontalScrollPolicy="off">
    <mx:Image width="100" height="100" source="{img}" id="image" x="150" y="122"/>
    <mx:Script>
        <![CDATA[
            private var targetX : Number;
            private var targetY : Number;
            private const speed : Number = 0.1;
           
            [Embed(source="../images/wisu_300.png")]
            [Bindable]
            private var img : Class;
           
            private function init() : void {
                addEventListener(Event.ENTER_FRAME, onEnterFrame);
                targetX = 0; targetY = 0;
            }
           
            private function onEnterFrame(event : Event) : void {
                var dx : Number = targetX - image.x;
                var dy : Number = targetY - image.y;
                image.x += dx * speed;
                image.y += dy * speed;
            }
           
            private function onMouseMove(event : MouseEvent) : void {
                targetX = event.stageX;
                targetY = event.stageY;   
            }
        ]]>
    </mx:Script>
</mx:Application>



2. 플렉스에서 애니메이션을 만드는 두번째 방법은 timer를 이용하는 것이다.
타이머는 원하는 시간마다 특정함수가 호출되도록 하는 이벤트이다.
타이머를 사용하기 위해서는 일단 타이머 객체를 생성해야 한다.

private var timer : Timer = new Timer(30);

이렇게 해주면 30밀리초마다 호출되는 타이머 객체가 만들어지는 것이다.
그리고 나서 이벤트 리스너를 등록해야한다.

timer.addEventListener(TimerEvent.TIMER, onTimer);

이렇게 하면 타이머 리스너가 등록된 것이다. 그런데 여기서도 마찬가지로 onTimer함수를 정의해줘야 한다.
private function onTimer(event : TimerEvent) : void {
  //매 30밀리초마다 해야할 작업을 작성한다.
}

이렇게 등록을 했다면 타이머를 시작시켜줘야한다. 타이머는 enterFrame과는 다르게 시작을 해주지 않으면 동작하지 않는다.

timer.start(); 

이렇게 start()메소드를 호출해 줌으로써 이제 타이머가 동작하게 되는 것이다.
만약 타이머를 정지시키고 싶다면 stop()메소드를 호출해야한다.

timer.stop();

이제 타이머를 이용해서 위에서 만든 마우스를 따라 움직이는 애니메이션을 만들어보자.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" mouseMove="onMouseMove(event)" width = "400" height = "400" verticalScrollPolicy="off" horizontalScrollPolicy="off">
    <mx:Image width="100" height="100" source="{img}" id="image" x="150" y="122"/>
    <mx:Script>
        <![CDATA[
            private var targetX : Number;
            private var targetY : Number;
            private const speed : Number = 0.1;
            private var timer : Timer;
           
            [Embed(source="../images/wisu_300.png")]
            [Bindable]
            private var img : Class;
           
            private function init() : void {
                timer = new Timer(30);
                timer.addEventListener(TimerEvent.TIMER, onTimer);
                timer.start();
                targetX = 0; targetY = 0;
            }
           
            private function onTimer(event : TimerEvent) : void {
                var dx : Number = targetX - image.x;
                var dy : Number = targetY - image.y;
                image.x += dx * speed;
                image.y += dy * speed;
            }
           
            private function onMouseMove(event : MouseEvent) : void {
                targetX = event.stageX;
                targetY = event.stageY;   
            }
        ]]>
    </mx:Script>
</mx:Application>



이렇게 enterFrame과 timer를 이용해서 애니메이션을 구현해 보았는데 동작하는 모습은 똑같다.
그런데 이렇게 애니메이션을 사용할 때에는 주의해야할 점이 있다.
이번에 프로젝트를 진행해보면서 느낀 점인데, 애니메이션을 보여주기 위해 계속해서 어떤 연산을 수행한다면 다른 컴포넌트가 업데이트 될 충분한 시간을 주지 못한다는 것이다.
그래서 기능적인 면이 우선시 되는 프로젝트라면 애니메이션이 그 기능을 제한하지 않는 범위 내에서 사용될 수 있도록 해야할 것이다.
신고
Posted by Code-Moon

댓글을 달아 주세요

  1. 버젼업 2012.05.16 14:22 신고 Address Modify/Delete Reply

    var icx:Number = image.width / 2 + image.x; // 이미지의 정확한 중간 좌표 x
    var icy:Number = image.height / 2 + image.y; // 이미지의 정확한 중간 좌표 y

    var dx:Number=targetX - icx;
    var dy:Number=targetY - icy;

플래시 플레이어 디버거는 플렉스에서 작업을 하는 동안 디버깅을 할 필요가 있는데 이 때 꼭 필요한 디버깅 툴이다.  그래서 오늘은 플래시 플레이어 디버거를 설치하는 방법에 대해 알아보자.

먼저 자신의 컴퓨터에 flash player debugger가 설치되어 있는지 확인해야 한다.
이를 위해서는 플래시 또는 플렉스가 동작하고 있는 브라우저에서 오른 클릭을 해보자.


아마 대부분의 사람들이 아래와 같은 화면을 볼 수 있을 것이다.
사용자 삽입 이미지

하지만 디버깅이 가능하기 위해서는 다음과 같은 화면이 나와야 한다.
사용자 삽입 이미지


두 화면의 차이를 알겠는가?
바로 "디버거"의 유무이다.

대부분의 사용자는 플래시 플레이어는 설치되어 있지만 플래시 플레이어 디버거는 설치되어 있지 않다. 그래서 이를 설치해줘야 한다.

플래시 플레이어 및 디버거를 다운로드하기 위해서는 아래 사이트로 가자.
http://www.adobe.com/support/flashplayer/downloads.html

여기에서 최신 버전의 debugger를 다운 받는다.
이 때 주의할 점은 다운로드 페이지의 상단에 바로 보이는 Get the latest version(아래 이미지)으로 받으면 안된다는 것이다. 이 버전은 플래시 플레이어일 뿐, 디버깅은 안된다.
사용자 삽입 이미지

다운로드 페이지에서 아래로 조금만 내려보면 아래 이미지와 같이 Debugger Versions을 볼 수 있다.
사용자 삽입 이미지

여기에서 자신이 사용하는 디버깅용 브라우저에 맞는 것을 다운로드 하도록 하자.
참고로 본인은 디버깅할 때 IE를 사용하기 때문에 Downlaod the Windows Flash Player 10 ActiveX control content debugger (for IE)를 다운받아서 설치했다.

디버거를 다운로드했다면 이제 언인스톨러(uninstaller)를 다운받아야 한다.
언인스톨러를 이용해서 기존의 플래시 플레이어를 삭제하지 않으면 제대로 설치되지 않을 수도 있기 때문에 꼭 필요하다.
언인스톨러는 다운로드 페이지의 상단에 보면 Uninstallers가 링크되어 있다.
사용자 삽입 이미지

여기에서 Uninstallers링크를 따라가 보면 아래와 같은 화면으로 내려가게 된다.
사용자 삽입 이미지
여기에서 Tech Note링크를 따라가면 언인스톨러를 다운받을 수 있을 것이다.

이렇게 플래시 플레이어 디버거언인스톨러를 다운 받았다면 이제 준비는 끝난 것이다.
그러면 현재 작업하고 있는 웹 브라우저를 모두 닫고, 언인스톨 -> 플래시 플레이어 디버거 설치 순으로 진행하면 된다.
신고
Posted by Code-Moon

댓글을 달아 주세요

  1. BlogIcon 웹눈 2010.05.05 09:21 신고 Address Modify/Delete Reply

    감사합니다. ^^

티스토리 툴바