최근 스티브잡스횽이 까고 있는 플래시-_-

CS5 한글판이 나와서 한번 깔아봤는데, 역시 전 한글이 편하네요-_- 어설픈 한글로 되어있어도 그냥 영어로 된 것 보단 낫다고 생각하는 1人...

일단 Flash랑 Flash Builder를 둘 다 깔아야해요~
안깔면 안깔려있다고 뭐라그래요~

일단 Flash에서 액션스크립트 편집기가 좋아졌다고 하는데(전 잘 안써봐서-_-), 여전히 안좋은 것 같은 느낌이 드는....
액션스크립트 클래스 편집은 그냥 Flash Builder에서 하면 맘 편하네요~
둘이서 연동이 되어서 빌더에서 에러 수정 및 편집이 매우 용이해요~

일단 플래시화면!
사용자 삽입 이미지
일단 Flash Builder도 같이 띄워놓아야 합니다. 안그러면 선택하라는 거 안나오는 것 같음.
여기서 ActionScript3프로젝트로 새로 만든다음에, ActionScript 3.0 클래스를 새로 만들면
"어떤 응용 프로그램에서 ActionScript3.0 클래스를 만들어야 합니까?"라는 말로 물어보고, Flash Professional인지 Flash Builder인지 선택할 수 있어요.
그러면 Flash Builder에서 해당 Flash프로젝트 파일인 fla파일을 선택하면 되는데요. 그러면 자동으로 프로젝트도 만들고, ActionScript Class만드는 창도 떠서 만들어지게 됩니다.
[code]package
{
    import flash.display.Sprite;

    public class DrawRect extends Sprite
    {
        public function DrawRect()
        {
            this.graphics.beginFill(0x000000);
            this.graphics.drawRect(0, 0, 100, 100);
            this.graphics.endFill();
        }
    }
}[/code]
사각형을 그리고~ flash에서 불러올 때 자동으로 DrawRect라는 클래스가 코드힌트로 나옴!
사용자 삽입 이미지

[code]var drawRect:DrawRect = new DrawRect();
this.addChild(drawRect);[/code]

사용자 삽입 이미지
잼있는 건 Flash Builder에서도 Control + Enter눌러도 된다는......
일단....여전이 Flash에서 ActionScript편집은 불편합니다. 그래서 얘네들이 Flash Builder 연동을 해서 하는 것 같은데, 정말 괜찮은 기능인 듯 합니다.
 
Posted by 머드초보
,
 
와~ 컨퍼런스다~ 전 이런곳을 참 좋아하는....-_-(카페활동도 안하고 눈팅만 하는 놈이.....-_-)
게다가 우리회사 근처에서 하네요. 매우 익숙한 AT센터의 숨막히는 뒷태.

암튼, 주말인데도 불구하고, 저의 출근버스 9500번을 타고, 마치 출근하는 기분으로 갔습니다ㅠㅠ
좀 늦게 갔는데, 이미 문군님이 발표를 하고 계시네요.


1. 디자이너를 위한 플래시 - 문군님

음... 늦게 가서 제대로 못들었습니다 ㅠㅠㅠㅠ


2. 쉽게 접하는 플래시 아트웍 - 공씨님

와~ KSUG(한국 스프링 유저 모임)에서나 볼 수 있던 라이브코딩이네요!
예전에 플래시캠프서울 행사에서 보던 플래시 아트를 주제로 했는데요. 그때에도 매우 멋있다고 생각했었는데, 이런 짓(?)을 하시는 분이 국내에도 계셨군요!
하지만, 확실히 국내에서의 돈이 되는 플래시는 아니기때문에-_- 취미로 하고 계시다고 하네요.

일단 아무것도 없는 상태에서 라이브코딩으로 모든 것을 진행했습니다. Flash에다가 아무것도 draw하지 않고, 오직 ActionScript로만 코드를 작성했습니다.
그랬는데, 매우 아름다운 영상이 나왔네요. 중간에 라이브코딩을 해서 오류도 나고 실수도 좀 했지만(신기한 건 진짜 아무것도 준비를 해오지 않고 온 듯한 느낌을 좀 받았음 ㄷㄷ), 결국에는 멋진 아트웍을 한시간안에 만들어버렸네요~ 와 이거 참 재미있네요~ 저도 나중에 시간나면 해봐야겠어요!

공씨님은 발표도 참 잘하시고, 코딩도 참 잘하시네요! 부럽 ㅠㅠ
그 만든 코드를 좀 보고 싶은데....카페에 올라오려나.....


3. Flash CS5 for iPhone - 우야꼬님

애플의 변경된 정책과 어도비에서 포기로 인해 발표안할 줄 알았는데, 그냥 했네요~^^
확실히 Flash로 아이폰앱을 개발하게 된다면 그래픽그리고, 모션을 하는 부분에 대해서는 매우 쉽게 개발할 수 있겠지요^^ 하지만, 제 생각은 조금 틀렸던 것이.... 실제로 애플에서 제공하는 것은 Objective-C를 통한 개발인데, 그걸 Flash로 개발해서 억지로 iPhone에 맞게 변형해서 끼워맞춘다는 것 자체가 깔끔하지도 못하고 한번의 변환과정을 거치는 것이라 퍼포먼스, 호환성 등에 뭔가 문제가 생길 것이라는 생각이 조쿰 들었습니다.
그래서 좀 원하지 않았는데, 그래도 어도비에서 포기했다니 다행이네요-_- 이런건 시작하지 말았어야....-_-

어쨌든, 저번에 Flash Camp Seoul행사에서도 cs5를 이용한 아이폰개발을 보여주었는데요. 참 신기하긴 합니다. 뭐 안드로이드로 퍼블리싱이 가능하게 한다고 합니다. 확실히 플래시로 개발하게 되는 장점은 그것이네요. 그래픽에서 매우 자유롭죠. 웹에서도 항상 html + css + js환경에선 그리는 것에 대해서 한계가 있었고, 그걸 플래시가 보완해주는 형태였는데, 안드로이드에서도 그래픽을 그리기위해선 매우 큰 고통이 필요합니다-_- 그걸 쉽게 해주는 것은 확실히 플래시가 좋긴 합니다.
하지만, 어플형태로 제작하게 된다면..플래시로 개발하면 안되겠죠-_-
안드로이드도 나름 컴포넌트가 잘 되어있어서 개발을 빠르게 할 수 있죠.

어쨌든, 우야꼬님이 마지막에 좋은 얘기를 해주셨는데요. 원하는 걸 만들고 싶으면 그냥 계속 삽질하라는....(제 귀에는 그냥 이렇게 들리네요-_-)



4. 플래시 플랫폼으로 표현하는 SNS - 러브데브님

오창훈님이신데, 예전에 Daum DevDay때보고 1년만에 뵙는군요^^
암튼, 네이버에서도 하고 있는 OpenSocial을 얘기하러 나오신 것 같습니다. 확실히 Facebook에서 하고 있는 소셜게임이 외국에서는 굉장히 인기가 있는 것이 사실입니다. 하지만, 아직 국내에서는 Facebook만큼의 인맥이 구축된 인터넷서비스는 싸이월드 뿐인데, 싸이월드에서 그나마 소셜게임이 조금 선전을 하고 있죠~ 하지만, 아직 도토리 현질(?)수준이 아직은 많이 미약한 듯.
러브데브님 말대로 시장은 계속 커질 것이라는 기대가 조금 있긴하네요. 일단 싸이월드는 컴퓨터를 잘 모르는 사람들도 많이 하니깐요. 지금 싸이월드 소셜앱설치수가 많은 건 80만명까지 되는 걸보니.....-_-

일단 하고 싶은 얘기는 소셜앱을 만드는데에는 최적의 플랫폼이 플래시라는 것입니다. 저도 물론 그렇게 생각하구요. 아직까지 국내나 외국에서 ie점유율이 이렇게 높은데, html + js + css조합으로는 표현의 한계가 있게 되죠. 그래서 대부분의 소셜게임은 플래시로 제작이 되어있구요.
제가 생각하는 것과 많이 비슷하네요. 저도 플래시는 깔끔하게 swf파일 하나로 내려지기때문에-_-(의외로 깔끔한 걸 좋아한다는ㅜㅜ), 그리고 크로스플랫폼에 대한 개발이 편하기 때문에 등등~

그리고 마지막에 me2day를 이용한 오픈소셜을 소개시켜주셨네요. 예전에 네이버도 오픈소셜에 참여한다고 들었는데, 미투데이로 하는 것이네요. 미투데이는 아직 싸이월드만큼 인맥구축은 없지만, 이제 계속 성장하고 있는 서비스라서 소셜앱을 제작하면 많이 할 것 같습니다. 국내에서도 킬러앱수준의 소셜게임이 얼른 나왔으면 하네요^^

5. ??? - ???

아젠다에는 자수님으로 되어있는데... sk컴즈에서 일하시는 분 같은데, 검색위젯, 싸이월드 뮤직스킨에 대해서 발표를 하셨네요.
아....이때 친구가 와서 옆에서 기아와 롯데전을 시청하느라... 제대로 발표를 못들었어요.....ㅠㅠㅠㅠㅠ


오늘 발표는 참 재미있었네요~ 제가 좋아하는 플래시얘기만 잔뜩 들을 수 있는 기회였으니까요^^
최근 개발자들 사이에선 플래시가 참 많이 언급이 되었지요. 스티브잡스가 매우 까서....-_- 그래도 플래시는 참 좋은 기술인 것 같습니다.

PS. 스티브잡스는 언제까지 플래시를 깔것인가.....하긴 Adobe가 게으른건 사실이야-_-
 
Posted by 머드초보
,
 
ServerSocket이라는 것이 Adobe AIR 2에서 생겼는데요.
뭐 특별히 제약사항같은 것은 없는 것 같군요. 그냥 서버소켓 만들어서 쓰면 됩니다.

우선 Adobe AIR 2 셋팅Flash Builder를 다운로드

서버소켓 생성하는 방법은
new ServerSocket();
serverSocket.bind(포트, "아이피");
serverSocket.listen();
하면 서버소켓이 생성됩니다.

Event.Connect를 이벤트 추가하면 상대방이 연결해왔을 때 호출이 됩니다.
보통 Java에서는 Thread를 통해서 하게 되는데, Actionscript3는 특성상 이벤트기반이기에... 그냥 여러개가 연결이 되도 이벤트가 발생하고, 그 발생한 이벤트객체에서 socket이 들어있어서 그걸 이용하면 되구요.

그 소켓에 다시 이벤트를 걸어주면 됩니다. 그 소켓은 client와 연결된 소켓! 기존 client소켓처럼 쓰면 됩니다^^
데이터는 read, write로 주고 받으면 되죠.

아래는 간단한 예제를....-_-
ServerSocketTest.mxml
[code]<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/halo"
                       applicationComplete="windowedapplication_applicationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import flash.events.Event;
            import flash.events.IOErrorEvent;
            import flash.events.ProgressEvent;
            import flash.events.ServerSocketConnectEvent;
            import flash.net.ServerSocket;
            import flash.net.Socket;
           
            import mx.events.FlexEvent;
           
            private var socketPolicyUtil:SocketPolicyUtil;
           
            private var serverSocket:ServerSocket;
            private var listSocket:Vector.<Socket>;
           
            protected function windowedapplication_applicationCompleteHandler(event:FlexEvent):void
            {
                socketPolicyUtil = new SocketPolicyUtil();
               
                // 소켓리스트 초기화
                listSocket = new Vector.<Socket>;
               
                serverSocket = new ServerSocket();
               
                serverSocket.addEventListener(Event.CONNECT, connectHandler);
                serverSocket.addEventListener(Event.CLOSE, onClose);
       
                serverSocket.bind(10000, "127.0.0.1");
               
                serverSocket.listen();
                trace("Listening on " + serverSocket.port);
            }

            private function connectHandler(event:ServerSocketConnectEvent):void
            {
                // The socket is provided by the event object
                var socket:Socket = event.socket as Socket;
                listSocket.push(socket);
               
                socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
                socket.addEventListener(Event.CLOSE, onClientClose);
                socket.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
               
                socket.writeUTFBytes("Connected.");
                socket.flush();
               
                trace("Sending connect message");
            }
           
            private function socketDataHandler(event:ProgressEvent):void
            {
                var socket:Socket = event.target as Socket;
               
                // Read the message from the socket
                var message:String = socket.readUTFBytes(socket.bytesAvailable);
                trace("Received: " + message);
               
                // 등록된 소켓에 모두 전송
                for each (var s:Socket in listSocket)
                {
                    s.writeUTFBytes(message);
                    s.flush();
                }
            }
           
            private function onClientClose(event:Event):void
            {
                trace("Connection to client closed");
                var socket:Socket = event.target as Socket;
               
                // 등록된 소켓 삭제
                var i:int = 0;
                for each(var s:Socket in listSocket)
                {
                    if (s == socket)
                    {
                        trace("같음");
                        listSocket.splice(i, 1);
                        return;
                    }
                    i++;
                }
            }
           
            private function onIOError(event:IOErrorEvent):void
            {
                trace("IOError: " + event.text);   
            }
           
            private function onClose(event:Event):void
            {
                trace("Server socket closed by OS.");       
            }
        ]]>
    </fx:Script>
   
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
</s:WindowedApplication>
[/code]
그냥 코드만 봐도 그리 어렵지 않아요.
서버소켓을 생성하고, 연결되는 소켓들은 list(Vector)에 추가해서 관리하게 되고, 끊어지면 list에서 빼버리고, 대화요청이 들어오면 받아서 모두에게 뿌려주면 돼요.

여기서 제가 만든 클래스가 하나 있는데요. SocketPolicyUtil클래스인데, 크로스 도메인을 위한 클래스입니다. 아래에서 설명을....-_-


크로스 도메인 설정 클래스
여기서 제가 보안샌드박스를 위한 클래스를 하나 만들었는데요. 크로스도메인에서 socket요청이 들어온 경우에는 crossdomain.xml을 넘겨줘야하는데, 그것도 air에서 다 할 수 있습니다.
타 도메인에서 요청하는 경우, 클라이언트 측에서는 843포트를 통해 crossdomain.xml을 요청하게 되어있습니다. 물론 클라이언트에서 843이 아닌 다른 포트로 요청을 원하면 바꿀 수 있지요.
 클라이언트 측에 이런 코드를 넣으면 되죠. 그러면 10001로 포트를 요청하죠.
[code]Security.loadPolicyFile("xmlsocket://127.0.0.1:10001");[/code]
SocketPolicyUtil.as
[code]package
{
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.ServerSocketConnectEvent;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.ServerSocket;
    import flash.net.Socket;

    public class SocketPolicyUtil
    {
        private var serverSocket:ServerSocket;
       
        public function SocketPolicyUtil(port:int = 843)
        {
            serverSocket = new ServerSocket();
            serverSocket.bind(port, "127.0.0.1");
            serverSocket.listen();
            serverSocket.addEventListener(Event.CONNECT, connectHandler);
            serverSocket.addEventListener(Event.CLOSE, onClose);
        }
       
        private function connectHandler(event:ServerSocketConnectEvent):void
        {
            var socket:Socket = event.socket as Socket;
           
            socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
            socket.addEventListener(Event.CLOSE, onClientClose);
            socket.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
           
            trace("Policy Connected.");
        }
       
        private function socketDataHandler(event:ProgressEvent):void
        {
            var socket:Socket = event.target as Socket;
           
            var message:String = socket.readUTFBytes(socket.bytesAvailable);
            trace("Policy received : " + message);
           
            var file:File = new File(File.applicationDirectory.nativePath + File.separator + "policy.xml");
            var stream:FileStream = new FileStream();
            stream.open(file, FileMode.READ);
            var data:String = stream.readUTFBytes(stream.bytesAvailable);
            trace("policy data = " + data);
            socket.writeUTFBytes(data);
            socket.writeByte(0);
            socket.flush();
        }
       
        private function onClientClose(event:Event):void
        {
            trace("Policy close");
            removeClientSocketEvent(event.target as Socket);
        }
       
        private function onIOError(event:IOErrorEvent):void
        {
            trace("ioerror = " + event.text);   
        }
       
        private function onClose(event:Event):void
        {
            trace("Server socket closed by OS.");
        }
       
        private function removeClientSocketEvent(socket:Socket):void
        {
            socket.removeEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
            socket.removeEventListener(Event.CLOSE, onClientClose);
            socket.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);   
        }
    }
}[/code]
중요한 점은 policy.xml파일 날릴 때 마지막에 writeByte(0)으로 끝을 맺어줘야한다는...
이 클래스를 보면 policy.xml파일은 File.applicationDirectory에서 찾고 있으니 이걸 src폴더에다가 넣어버리고 패키지할 때 같이 묶어버리면 됩니다. 그리고 그냥 843포트로 열어서 crossdomain.xml파일을 그냥 전송해주기만 하면 되죠. *는 권장사항이 아니니...-_- 해당 도메인이랑 포트번호를 정확히 입력하는게...-_-
policy.xml
[code]<?xml version='1.0' encoding='UTF-8'?>
<cross-domain-policy>
    <allow-access-from domain='*' to-ports='*'/>
</cross-domain-policy>[/code]

아래는 클라이언트 코드
ClientSocketTest.mxml
[code]<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
               applicationComplete="application1_applicationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.events.FlexEvent;

            private var socket:Socket;
           
            protected function application1_applicationCompleteHandler(event:FlexEvent):void
            {
                //Security.loadPolicyFile("xmlsocket://127.0.0.1:10001");
            }

            protected function btnDisconnect_clickHandler(event:MouseEvent):void
            {
                if (inputId.text.length < 1)
                {
                    Alert.show("아이디를 입력하세요");
                    return;
                }
                socket = new Socket("127.0.0.1", 10000);
                socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
                currentState = "connect";
                labelId.text = inputId.text;
            }
           
            protected function btnConenct_clickHandler(event:MouseEvent):void
            {
                socket.close();
                currentState = "disconnect";
            }
           
           
            private function socketDataHandler(event:ProgressEvent):void
            {
                var message:String = socket.readUTFBytes(socket.bytesAvailable);
                trace("message = " + message);
                taChat.text += message + "\n";
            }

            protected function inputChat_enterHandler(event:FlexEvent):void
            {
                if (inputChat.text.length < 1)
                {
                    return;
                }
                socket.writeUTFBytes("[" + labelId.text + "] : " + inputChat.text);
                socket.flush();
                inputChat.text = "";
            }

            protected function btnChat_clickHandler(event:MouseEvent):void
            {
                if (inputChat.text.length < 1)
                {
                    return;
                }
                socket.writeUTFBytes("[" + labelId.text + "] : " + inputChat.text);
                socket.flush();
                inputChat.text = "";
            }
        ]]>
    </fx:Script>
    <s:states>
        <s:State name="disconnect"/>
        <s:State name="connect"/>
    </s:states>
   
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
   
    <s:TextInput id="inputId" x="231" y="10" includeIn="disconnect"/>
    <s:Button id="btnConenctClose" x="367" y="11" label="접속" label.connect="종료"
              click.connect="btnConenct_clickHandler(event)" click.disconnect="btnDisconnect_clickHandler(event)"/>
    <s:Label id="labelId" includeIn="connect" x="211" y="10" width="159" height="21"/>
   
    <s:TextArea id="taChat" includeIn="connect" x="10" y="49" width="621" height="402"/>
    <s:TextInput id="inputChat" includeIn="connect" x="10" y="459" width="507" enter="inputChat_enterHandler(event)"/>
    <s:Button id="btnChat" includeIn="connect" x="526" y="459" label="Button" click="btnChat_clickHandler(event)"/>
</s:Application>[/code]

아래 프로그램 설치하고 실행시켜놓은 뒤, 아래사이트를 접속해서 테스트할 수 있어요. 아이피는 127.0.0.1로 하드코딩되어있기 때문에 자기 pc에서 띄워놓고 자기가 접속한 클라이언트에서만 가능해요^^
클라이언트 접속 http://mudchobo.tomeii.com/swf/ClientSocketTest.swf


 
Posted by 머드초보
,
 
Adobe AIR 2.0 Beta가 Release되었네요.
Adobe AIR Team 블로그 글 - http://blogs.adobe.com/air/2009/11/adobe_air_2_beta_now_available.html

릴리즈노트는 여기서 - http://labs.adobe.com/wiki/index.php/AIR_2:Release_Notes#Overview

저의 짧은 실력의 릴리즈 노트를 보면......-_-

1. 해당 파일에 대한 기본 애플리케이션으로 지정된 프로그램을 실행할 수 있습니다. 이게 뭔 얘기냐면 doc파일이 word에 지정되어있으면 doc파일을 열어서 word를 실행할 수 있는 기능인 듯-_-

2. 마이크 데이터 엑세스. 마이크 데이터를 저장하고 뭐 삽질할 수 있나봅니다.

3. 대용량 저장소에 대한 발견이 가능해졌는데요. 예를 들어 USB를 연결하게 되면 그걸 AIR프로그램에서 인식할 수 있습니다.

4. 업데이트된 WebKit version. air에서 사용하는 브라우저엔진이 그냥 업데이트 됐다는 것 같은.....

5. 글로벌 에러 핸들링은 뭐지.....

6. 새로운 네트워크 지원. AIR프로그램이 서버프로그램이 될 수 있게 ServerSocket을 지원하네요. 그 외에 UDP랑 TLS/SSL도 지원한다고 써있지만, UDP빼곤 잘 몰라서-_-
아.....네트워크 인터페이스 목록이라는 부분은 그거 같은데, 네트워크 정보를 얻어올 수 있는 그런거. 맥어드레스같은 거 AIR에서 못 읽어왔는데, 읽어올 수 있나봅니다.

7. EXE파일의 PACKAGING이 가능. 원래 AIR파일이 나오는데, 이제 exe파일로도 패키징을 할 수 있습니다.

8. native process API. 이건 다른 프로그램을 AIR프로그램이 실행할 수 있는 API인데, 조금 삽질해보니 제약이 좀 있음. 패키징할 때 지정한 것만 되는 것 같음. 좀 더 삽질을 해봐야할 듯 ^^ 암튼, 프로그램을 제약적이지만 실행할 수 있어요.

9. 데이터베이스 트랜젝션 어쩌구 하는데 잘 모르겠음

다 적으려니까 디게 많네.....-_-
그냥 그외에, 향상된 IPv6을 지원하고, Native Window의 최대사이즈를 증가시켰고, 멀티터치지원하고, IME향상시켰고....영어공부해야겠다.

구축하기에 앞서 Flash Builder 4 Beta 2 다운로드

1. 개발환경 구축
사실 개발환경 구축이라고 하기에는 너무나 간단하지만....-_- 그냥 AIR SDK받아서 Flash Builder 4가 설치된 폴더 안에 있는 sdk에 덮어 씌우면 됩니다.
우선 Adobe AIR 2 Beta SDK와 Runtime 다운로드 - http://labs.adobe.com/downloads/air2.html
받은 sdk파일 (air2_b1_sdk_win_11709.zip)을 Flash Builder 2 sdk폴더에 압축을 덮어씌워서 풀어버립니다. 저의 경로는 아래와 같군요.
C:\Program Files (x86)\Adobe\Adobe Flash Builder Beta 2\sdks\4.0.0

2. 개발하면 돼요-_-

3. 예제 작성
[code]<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/halo"
                       width="500" height="500"
                       applicationComplete="windowedapplication1_applicationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import flash.events.StorageVolumeChangeEvent;
            import mx.events.FlexEvent;

            protected function windowedapplication1_applicationCompleteHandler(event:FlexEvent):void
            {
                StorageVolumeInfo.storageVolumeInfo.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_MOUNT, mountHandler);
                StorageVolumeInfo.storageVolumeInfo.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_UNMOUNT, unmountHandler);
            }
           
            private function mountHandler(event:StorageVolumeChangeEvent):void
            {
                trace(event.rootDirectory.nativePath);   
                taInfo.text += "drive = " + event.storageVolume.drive + ", type = " +
                    event.storageVolume.fileSystemType + ", name = " + event.storageVolume.name + "\n";
            }
           
            private function unmountHandler(event:StorageVolumeChangeEvent):void
            {
                taInfo.text += event.rootDirectory.nativePath + " 제거됨\n";
            }
        ]]>
    </fx:Script>
    <s:TextArea id="taInfo" x="6" y="10" width="484" height="480" verticalScrollPolicy="on"/>
</s:WindowedApplication>[/code]

핵심은 StorageVolumeInfo클래스랑 StorageVolumeChangeEvent클래스입니다. 그냥 MOUNT, UNMOUNT이벤트 걸어주면 지가 알아서 다함^^
사용자 삽입 이미지
참조사이트
http://www.adobe.com/devnet/air/flex/articles/exploring_file_capabilities.html
 
Posted by 머드초보
,
 
테스트의 중요성은 저번 스프링 강의시간에 충분히 느꼈습니다. 하지만, 역시 귀차니즘 때문에 잘 안만들게 되는 게 테스트인 듯 합니다. 하지만, 한번 만들어놓으면 이래저래 매우 유용한 것이 테스트죠.

다운로드는 여기서....-_-


Java에서는 Junit이라는 것이 있는데, 4버전에서는 Annotation(@)을 이용해서 쉽게 테스트를 만들곤 했는데요. Flex에서도 비슷한 기법을 이용합니다. 메타데이터를 위에다가 붙여서-_- 손쉽게 테스트를 만들 수 있습니다.
[code][Test]
public function testMyTest():void
{
}[/code]
와....Flash Builder를 보면 Java를 많이 따라한 것을 볼 수 있습니다. 예전엔 폴더생성으로만 만들 수 있었던 패키지가 직접적인 패키지 생성메뉴를 만들어서 Package Explorer에서 패키지형태로 볼 수 있습니다.
암튼, 자바와 닮아가는 듯-_-

1. 간단한 프로젝트 생성
Flex Project하나 생성.

2. 서비스 클래스 생성
덧셈 뺄셈 클래스하나 작성
com.mudchobo.test패키지의 Calc클래스 생성
Calc.as
[code]package com.mudchobo.test
{
    public class Calc
    {
        public function Calc()
        {
        }
       
        public function addition(a:Number, b:Number):Number
        {
            return a + b;
        }
       
        public function subtraction(a:Number, b:Number):Number
        {
            return a - b;   
        }
    }
}[/code]

3. 테스트 생성
New -> Test Case Class -> New FlexUnit 4 test선택. Name은 CalcTest로하고 Finish.
CalcTest.as
[code]package flexUnitTests
{
    import com.mudchobo.test.Calc;
   
    import flexunit.framework.Assert;

    public class CalcTest
    {
        private var calc:Calc;
       
        public function CalcTest()
        {
        }
       
        [Before]
        public function before():void
        {
            calc = new Calc();   
        }
       
        [Test]
        public function testAddition():void
        {
            var result:Number = calc.addition(50, 50);
            Assert.assertEquals(result, 100);
        }
       
        [Test]
        public function testSubtraction():void
        {
            var result:Number = calc.subtraction(50, 50);
            Assert.assertEquals(result, 0);
        }
    }
}[/code]
여기까지 작성하면 FlexUnitCompiler.mxml이라는 파일이 자동으로 생겼을겁니다. 이건 건드리지 않습니다. 검색해보니 이전방식으로 core생성해서 UIListener를 넣어서 하려고했는데, 이거 그렇게 하는게 아니더군요-_-
심지어 UIListener클래스는 없습니다-_-

4. 테스트 실행
테스트 실행은 package explorer에서 테스트클래스의 오른쪽 마우스버튼을 누르면 "Execute FlexUnit Tests"라는 메뉴가 있습니다. 그걸 선택하면 테스트가 됩니다. FlexUnitApplication.mxml파일도 같이 생기는군요.
테스트단축키는 Alt + Shift + E, F입니다....-_- 해당 편집파일에서 누르면 됩니다.
사용자 삽입 이미지
테스트 결과는 Junit처럼 이렇게 보여줍니다.
사용자 삽입 이미지
Junit이랑 똑같네.

5. 테스트 Suite 생성
이건 테스트를 다 모아서 실행하는 건데, 통합테스트를 할 때 사용하는 듯-_-
New -> Test Suite Class -> New FlesxxUnit4 test 하면 include할 테스트를 패키지에서 선택할 수 있습니다. 선택 후 Finish.
SuiteTest.as
[code]package flexUnitTests
{
    import flexUnitTests.CalcSecondTest;
    import flexUnitTests.CalcTest;
   
    [Suite]
    [RunWith("org.flexunit.runners.Suite")]
    public class SuiteTest
    {
       
        public var test1:flexUnitTests.CalcSecondTest;
        public var test2:flexUnitTests.CalcTest;
    }
}[/code]
그냥 저렇게 선언해두고, 오른쪽버튼 눌러서 "Execute FlexUnit Tests" or 알트 + 쉬프트 + E, F하면 통합테스트를 합니다.

6. 그외의 기능
저도 더 써봐야 알 것 같은데, Flex는 이벤트기반이다보니 Async와 UI구조가 많은데요. Async구조도 손쉽게 테스트를 할 수 있습니다.
[code][Test(async,ui)][/code]
이런식으로 하면 될 듯 한데, 안해봐서 잘 모르겠네요-_-

참고자료
http://www.insideria.com/2009/05/flashbuilder4-will-support-fle.html
http://balajisridhar.wordpress.com/2009/10/05/flexunit-integration-in-flash-builders-new-awatar-in-beta2/
 
Posted by 머드초보
,