공유 객체

Flash Player 9 이상, Adobe AIR 1.0 이상

"Flash 쿠키"라고도 하는 공유 객체는 방문한 사이트에서 사용자의 컴퓨터에 만들 수 있는 데이터 파일입니다. 예를 들어 자주 방문하는 웹 사이트의 모양과 느낌을 개인 설정할 수 있도록 하는 등의 방식으로 웹 브라우징 환경을 향상시키는 데 공유 객체가 가장 자주 사용됩니다.

공유 객체

공유 객체는 브라우저 쿠키처럼 작동합니다. SharedObject 클래스를 사용하여 데이터를 사용자의 로컬 하드 디스크에 저장해 놓았다가 동일한 세션 중에 또는 다른 세션에서 해당 데이터를 호출할 수 있습니다. 응용 프로그램은 동일한 도메인에서 실행되는 경우에 한해 해당 응용 프로그램 고유의 SharedObject 데이터에만 액세스할 수 있습니다. 데이터는 서버로 전송되지 않으며 다른 도메인에서 실행되는 다른 응용 프로그램에서는 액세스할 수 없습니다. 그러나 동일한 도메인의 응용 프로그램에서는 액세스 가능하도록 할 수 있습니다.

공유 객체와 쿠키 비교

쿠키와 공유 객체는 매우 비슷합니다. 대부분의 웹 프로그래머는 쿠키의 작동 방식을 잘 알고 있으므로 쿠키와 로컬 공유 객체를 비교하여 설명하면 도움이 될 것입니다.

RFC 2109 표준을 따르는 쿠키에는 일반적으로 다음과 같은 속성이 있습니다.

  • 쿠키는 만료될 수 있으며 기본적으로 세션 종료 시 만료되는 경우가 많습니다.

  • 클라이언트에서 사이트별로 쿠키를 비활성화할 수 있습니다.

  • 쿠키 수는 총 300개, 사이트당 최대 20개로 제한됩니다.

  • 일반적으로 각 쿠키의 크기는 4KB로 제한됩니다.

  • 쿠키가 보안 위협 요소로 파악되어 클라이언트에서 비활성화되는 경우도 있습니다.

  • 쿠키는 클라이언트 브라우저에서 지정한 위치에 저장됩니다.

  • 쿠키는 HTTP를 통해 클라이언트에서 서버로 전송됩니다.

    반면에, 공유 객체에는 다음과 같은 속성이 있습니다.

  • 공유 객체는 기본적으로 만료되지 않습니다.

  • 기본적으로 각 공유 객체의 크기는 100KB로 제한됩니다.

  • 공유 객체는 String, Array, Date 등의 단순 데이터 유형을 저장할 수 있습니다.

  • 공유 객체는 응용 프로그램에서 지정한 위치(사용자의 홈 디렉토리 내)에 저장됩니다.

  • 공유 객체는 클라이언트와 서버 간에 전송되지 않습니다.

SharedObject 클래스

SharedObject 클래스를 사용하면 사용 중인 SharedObject 객체의 현재 크기를 감지할 수 있을 뿐 아니라 공유 객체를 만들거나 삭제할 수도 있습니다.

공유 객체 만들기

SharedObject 객체를 만들려면 다음 구문이 있는 SharedObject.getLocal() 메서드를 사용합니다.

SharedObject.getLocal("objectName" [, pathname]): SharedObject

다음 예제에서는 mySO라는 공유 객체를 만듭니다.

public var mySO:SharedObject; 
mySO = SharedObject.getLocal("preferences");

이를 실행하면 클라이언트 컴퓨터에 preferences.sol이라는 파일이 만들어집니다.

local 이라는 용어는 공유 객체의 위치를 나타냅니다. 이 경우에는 Adobe® Flash® Player가 클라이언트의 홈 디렉토리에 로컬로 SharedObject 파일을 저장합니다.

공유 객체를 만들면 Flash Player가 샌드박스 내부에 응용 프로그램 및 도메인에 대한 새 디렉토리를 만듭니다. 또한 Flash Player가 SharedObject 데이터를 저장하는 *.sol 파일도 만듭니다. 이 파일의 기본 위치는 사용자 홈 디렉토리의 하위 디렉토리입니다. 다음 표에서는 이 디렉토리의 기본 위치를 보여 줍니다.

운영 체제

위치

Windows 95/98/ME/2000/XP

c:/Documents and Settings/username/Application Data/Macromedia/Flash Player/#SharedObjects

Windows Vista/Windows 7

c:/Users/username/AppData/Roaming/Macromedia/Flash Player/#SharedObjects

Macintosh OS X

/Users/username/Library/Preferences/Macromedia/Flash Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol

Linux/Unix

/home/username/.macromedia/Flash_Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol

#SharedObjects 디렉토리 아래에는 임의로 이름이 지정된 디렉토리가 있습니다. 그 아래에는 호스트 이름과 일치하는 디렉토리, 그 다음에는 응용 프로그램에 대한 경로, 마지막에는 *.sol 파일이 있습니다.

예를 들어 로컬 호스트의 /sos라는 하위 디렉토리 내에 있는 MyApp.swf라는 응용 프로그램을 요청하는 경우 Flash Player가 *.sol 파일을 Windows XP의 다음 위치에 저장합니다.

c:/Documents and Settings/fred/Application Data/Macromedia/Flash Player/#SharedObjects/KROKWXRK/#localhost/sos/MyApp.swf/data.sol
참고: SharedObject.getLocal() 메서드에 이름을 입력하지 않으면 Flash Player가 파일 이름을 undefined.sol로 지정합니다.

기본적으로 Flash는 도메인당 최대 100KB의 영구 SharedObject 객체를 로컬로 저장할 수 있습니다. 이 값은 사용자가 구성할 수 있습니다. 응용 프로그램에서 공유 객체에 저장하려는 데이터가 100KB를 초과하는 경우 Flash Player에 [로컬 저장소] 대화 상자가 표시되어 액세스를 요청하는 도메인의 로컬 저장소 크기 증가 허용 또는 거부를 사용자가 선택할 수 있도록 합니다.

경로 지정

선택적 매개 변수인 pathname 을 사용하여 SharedObject 파일의 위치를 지정할 수 있습니다. 이 파일은 해당 도메인의 SharedObject 디렉토리 내 하위 디렉토리여야 합니다. 예를 들어 로컬 호스트에 있는 응용 프로그램을 요청하는 경우 다음과 같이 지정합니다.

mySO = SharedObject.getLocal("myObjectFile","/");

Flash Player는 SharedObject 파일을 /#localhost 디렉토리에 기록합니다. 또는 응용 프로그램이 오프라인인 경우에는 /localhost에 기록합니다. 이는 클라이언트에 있는 둘 이상의 응용 프로그램이 동일한 공유 객체에 액세스할 수 있도록 하려는 경우에 유용합니다. 이 경우 클라이언트는 두 Flex 응용 프로그램을 실행할 수 있으며 두 응용 프로그램 모두 도메인의 루트에 있는 공유 객체에 대한 경로를 지정합니다. 그러면 클라이언트는 두 응용 프로그램 모두에서 동일한 공유 객체에 액세스할 수 있습니다. 일시적으로 여러 응용 프로그램 간에 데이터를 공유하려면 LocalConnection 객체를 사용합니다.

존재하지 않는 디렉토리를 지정하면 Flash Player에서 SharedObject 파일을 만들지 않습니다.

공유 객체에 데이터 추가

SharedObject 객체의 data 속성을 사용하여 SharedObject 의 *.sol 파일에 데이터를 추가합니다. 공유 객체에 새 데이터를 추가하려면 다음 구문을 사용합니다.

sharedObject_name.data.variable = value;

다음 예제에서는 SharedObject에 userName , itemNumbers adminPrivileges 속성과 해당 값을 추가합니다.

public var currentUserName:String = "Reiner"; 
public var itemsArray:Array = new Array(101,346,483); 
public var currentUserIsAdmin:Boolean = true; 
mySO.data.userName = currentUserName; 
mySO.data.itemNumbers = itemsArray; 
mySO.data.adminPrivileges = currentUserIsAdmin;

data 속성에 값을 할당한 후 SharedObject 파일에 해당 값을 기록하도록 Flash Player에 지시해야 합니다. SharedObject 파일에 값을 기록하도록 Flash Player에 지시하려면 다음과 같이 SharedObject . flush() 메서드를 사용합니다.

mySO.flush();

SharedObject.flush() 메서드를 호출하지 않으면 Flash Player가 응용 프로그램이 종료될 때 파일에 값을 기록합니다. 그러나 Flash Player가 저장해야 할 데이터의 크기가 기본 설정을 초과하는 경우 사용 가능한 공간을 늘릴 수 있는 기회가 사용자에게 제공되지 않습니다. 따라서 SharedObject.flush() 를 호출하는 것이 좋습니다.

flush() 메서드를 사용하여 공유 객체를 사용자의 하드 드라이브에 기록하는 경우 다음 예제에서 보듯이 사용자가 Flash Player 설정 관리자( www.macromedia.com/support/documentation/kr/flashplayer/help/settings_manager07.html )를 사용하여 명시적으로 로컬 저장을 사용하지 않도록 설정했는지 확인해야 합니다.

var so:SharedObject = SharedObject.getLocal("test"); 
trace("Current SharedObject size is " + so.size + " bytes."); 
so.flush();

공유 객체에 객체 저장

SharedObject의 data 속성에 Array 또는 String 등의 단순 객체를 저장할 수 있습니다.

다음 예제는 공유 객체와의 상호 작용을 제어하는 메서드를 정의하는 ActionScript 클래스입니다. 이러한 메서드를 사용하면 사용자가 공유 객체에서 객체를 추가하거나 제거할 수 있습니다. 이 클래스는 단순 객체가 포함된 ArrayCollection을 저장합니다.

package { 
    import mx.collections.ArrayCollection; 
    import flash.net.SharedObject; 
 
    public class LSOHandler { 
 
        private var mySO:SharedObject; 
        private var ac:ArrayCollection; 
        private var lsoType:String; 
 
        // The parameter is "feeds" or "sites". 
        public function LSOHandler(s:String) { 
            init(s); 
        } 
 
        private function init(s:String):void { 
            ac = new ArrayCollection(); 
            lsoType = s; 
            mySO = SharedObject.getLocal(lsoType); 
            if (getObjects()) { 
                ac = getObjects(); 
            } 
        } 
 
        public function getObjects():ArrayCollection { 
            return mySO.data[lsoType]; 
        } 
 
        public function addObject(o:Object):void { 
            ac.addItem(o); 
            updateSharedObjects(); 
        } 
 
        private function updateSharedObjects():void { 
            mySO.data[lsoType] = ac; 
            mySO.flush(); 
        } 
    } 
 
}

다음 Flex 응용 프로그램은 필요한 각 공유 객체 유형별로 ActionScript 클래스 인스턴스를 만듭니다. 그런 다음 사용자가 블로그나 사이트 URL을 추가 또는 제거할 때 해당 클래스에 대한 메서드를 호출합니다.

<?xml version="1.0"?> 
<!-- lsos/BlogAggregator.mxml --> 
<mx:Application 
    xmlns:local="*" 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    creationComplete="initApp()" 
    backgroundColor="#ffffff" 
> 
    <mx:Script> 
        <![CDATA[ 
        import mx.collections.ArrayCollection; 
        import mx.utils.ObjectUtil; 
        import flash.net.SharedObject; 
 
        [Bindable] 
        public var welcomeMessage:String; 
        
        [Bindable] 
        public var localFeeds:ArrayCollection = new ArrayCollection(); 
 
        [Bindable] 
        public var localSites:ArrayCollection = new ArrayCollection(); 
 
        public var lsofeeds:LSOHandler; 
        public var lsosites:LSOHandler; 
 
        private function initApp():void { 
            lsofeeds = new LSOHandler("feeds"); 
            lsosites = new LSOHandler("sites"); 
            
            if (lsofeeds.getObjects()) { 
                localFeeds = lsofeeds.getObjects(); 
            } 
            if (lsosites.getObjects()) { 
                localSites = lsosites.getObjects(); 
            } 
        } 
        
        // Adds a new feed to the feeds DataGrid. 
        private function addFeed():void { 
            // Construct an object you want to store in the 
            // LSO. This object can contain any number of fields. 
            var o:Object = {name:ti1.text, url:ti2.text, date:new Date()}; 
            lsofeeds.addObject(o); 
    
            // Because the DataGrid's dataProvider property is 
            // bound to the ArrayCollection, Flex updates the 
            // DataGrid when you call this method. 
            localFeeds = lsofeeds.getObjects(); 
            
            // Clear the text fields. 
            ti1.text = '';        
            ti2.text = ''; 
        } 
        
        // Removes feeds from the feeds DataGrid. 
        private function removeFeed():void { 
            // Use a method of ArrayCollection to remove a feed. 
            // Because the DataGrid's dataProvider property is 
            // bound to the ArrayCollection, Flex updates the 
            // DataGrid when you call this method. You do not need 
            // to update it manually. 
            if (myFeedsGrid.selectedIndex > -1) { 
            
localFeeds.removeItemAt(myFeedsGrid.selectedIndex); 
             } 
        } 
        
        private function addSite():void { 
            var o:Object = {name:ti3.text, date:new Date()}; 
            lsosites.addObject(o); 
            localSites = lsosites.getObjects(); 
            ti3.text = '';                
        } 
        
        private function removeSite():void { 
            if (mySitesGrid.selectedIndex > -1) { 
            
localSites.removeItemAt(mySitesGrid.selectedIndex); 
            }       
        } 
 
        ]]> 
    </mx:Script> 
        
    <mx:Label text="Blog aggregator" fontSize="28"/> 
    
    <mx:Panel title="Blogs"> 
        <mx:Form id="blogForm"> 
            <mx:HBox> 
                <mx:FormItem label="Name:"> 
                    <mx:TextInput id="ti1" width="100"/> 
                </mx:FormItem> 
                <mx:FormItem label="Location:"> 
                    <mx:TextInput id="ti2" width="300"/> 
                </mx:FormItem> 
                <mx:Button id="b1" label="Add Feed" click="addFeed()"/> 
            </mx:HBox> 
 
            <mx:FormItem label="Existing Feeds:"> 
                <mx:DataGrid 
                    id="myFeedsGrid" 
                    dataProvider="{localFeeds}" 
                    width="400" 
                /> 
            </mx:FormItem> 
            <mx:Button id="b2" label="Remove Feed" click="removeFeed()"/> 
        </mx:Form> 
    </mx:Panel> 
    
    <mx:Panel title="Sites"> 
        <mx:Form id="siteForm"> 
            <mx:HBox> 
                <mx:FormItem label="Site:"> 
                    <mx:TextInput id="ti3" width="400"/> 
                </mx:FormItem> 
                <mx:Button id="b3" label="Add Site" click="addSite()"/> 
            </mx:HBox> 
 
            <mx:FormItem label="Existing Sites:"> 
                <mx:DataGrid 
                    id="mySitesGrid" 
                    dataProvider="{localSites}" 
                    width="400" 
                /> 
            </mx:FormItem> 
            <mx:Button id="b4" label="Remove Site" click="removeSite()"/> 
        </mx:Form> 
    </mx:Panel> 
    
</mx:Application>

공유 객체에 유형이 지정된 객체 저장

공유 객체에 유형이 지정된 ActionScript 인스턴스를 저장할 수 있습니다. flash.net.registerClassAlias() 메서드를 호출하여 클래스를 등록하면 됩니다. 클래스의 인스턴스를 만들어 공유 객체의 데이터 멤버에 저장한 후 나중에 객체를 읽으면 유형이 지정된 인스턴스를 가져옵니다. 기본적으로 SharedObject의 objectEncoding 속성은 AMF3 인코딩을 지원하며 SharedObject 객체에서 저장된 인스턴스의 압축을 풉니다. 따라서 저장된 인스턴스의 유형은 registerClassAlias() 메서드를 호출할 때 지정한 유형과 동일하게 유지됩니다.

(iOS에만 해당) 로컬 공유 객체의 클라우드 백업 방지

SharedObject.preventBackup 속성을 설정하여 로컬 공유 객체를 iOS 클라우드 백업 서비스에 백업할지 여부를 제어할 수 있습니다. 이는 다시 생성하거나 다시 다운로드할 수 있지만 오프라인에서 사용할 때 응용 프로그램이 올바르게 작동하도록 하는 데 필요한 내용에 대한 Apple의 요구 사항입니다.

여러 공유 객체 만들기

동일한 Flex 응용 프로그램에 대해 여러 공유 객체를 만들 수 있습니다. 다음 예제에서 볼 수 있는 것과 같이 각 공유 객체에 서로 다른 인스턴스 이름을 할당하면 됩니다.

public var mySO:SharedObject = SharedObject.getLocal("preferences"); 
public var mySO2:SharedObject = SharedObject.getLocal("history");

그러면 Flex 응용 프로그램의 로컬 디렉토리에 preferences.sol 파일과 history.sol 파일이 만들어집니다.

보안 SharedObject 만들기

getLocal() 또는 getRemote() 를 사용하여 로컬 또는 원격 SharedObject를 만들 때 이 공유 객체에 대한 액세스를 HTTPS 연결을 통해 전달되는 SWF 파일로만 제한할지 결정하는 secure 라는 선택 매개 변수가 있습니다. 이 매개 변수를 true 로 설정하고 SWF 파일이 HTTPS를 통해 전달되면 Flash Player에서 새 보안 공유 객체를 만들거나 기존의 보안 공유 객체에 대한 참조를 가져옵니다. 이 보안 공유 객체는 보안 매개 변수가 true 로 설정된 SharedObject.getLocal() 을 호출하는 HTTPS를 통해 전달되는 SWF 파일에 의해서만 읽거나 쓸 수 있습니다. 이 매개 변수를 false 로 설정하고 SWF 파일이 HTTPS를 통해 전달되면 Flash Player에서 새 공유 객체를 만들거나 기존의 공유 객체에 대한 참조를 가져옵니다.

이 공유 객체는 HTTPS가 아닌 연결을 통해 제공되는 SWF 파일에 의해 읽거나 쓸 수 있습니다. SWF 파일이 비 HTTPS 연결을 통해 전달되고 이 매개 변수를 true 로 설정하려고 하면 새 공유 객체를 만들지 못하고(또는 이전에 만든 보안 공유 객체에 대한 액세스하지 못함), 오류가 발생하며, 공유 객체가 null 로 설정됩니다. HTTPS가 아닌 연결에서 다음 코드를 실행하려고 하면 SharedObject.getLocal() 메서드에서 오류를 발생시킵니다.

try 
{ 
    var so:SharedObject = SharedObject.getLocal("contactManager", null, true); 
} 
catch (error:Error) 
{ 
    trace("Unable to create SharedObject."); 
}

만들어진 공유 객체는 이 매개 변수 값에 상관없이 도메인에 허용된 총 디스크 공간에 반영됩니다.

공유 객체의 내용 표시

값은 data 속성 내에 있는 공유 객체에 저장됩니다. 다음 예제에 표시된 대로 for..in 루프를 사용하여 공유 객체 인스턴스의 각 값을 반복할 수 있습니다.

var so:SharedObject = SharedObject.getLocal("test"); 
so.data.hello = "world"; 
so.data.foo = "bar"; 
so.data.timezone = new Date().timezoneOffset; 
for (var i:String in so.data) 
{ 
    trace(i + ":\t" + so.data[i]); 
}

공유 객체 삭제

클라이언트에서 SharedObject 를 삭제하려면 SharedObject.clear() 메서드를 사용합니다. 이 메서드를 사용해도 응용 프로그램의 공유 객체에 대한 기본 경로의 디렉토리는 삭제되지 않습니다.

다음 예제를 실행하면 클라이언트에서 SharedObject 파일이 삭제됩니다.

public function destroySharedObject():void { 
    mySO.clear(); 
}

SharedObject 예제

다음 예제에서는 해당 객체를 수동으로 직렬화하거나 직렬화를 해제하지 않고도 Date 객체와 같은 간단한 객체를 SharedObject 객체에 저장할 수 있음을 보여 줍니다.

다음 예제는 첫 번째 방문을 환영한다는 메시지로 시작합니다. 사용자가 [Log Out]을 클릭할 때 응용 프로그램에서 공유 객체에 현재 날짜를 저장합니다. 다음에 이 응용 프로그램을 시작하거나 페이지를 새로 고치면 다시 방문한 것을 환영하는 메시지와 함께 지난 번에 로그아웃한 시간을 알려 줍니다.

응용 프로그램의 동작을 확인하려면 응용 프로그램을 시작하고 [Log Out]을 클릭한 다음 페이지를 새로 고치십시오. 그러면 이전 방문 시 [Log Out] 버튼을 클릭했던 날짜 및 시간이 표시됩니다. 언제든지 [Delete LSO] 버튼을 클릭하여 저장된 정보를 삭제할 수 있습니다.

<?xml version="1.0"?> 
<!-- lsos/WelcomeMessage.mxml --> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initApp()"> 
  <mx:Script><![CDATA[ 
  public var mySO:SharedObject; 
  [Bindable] 
  public var welcomeMessage:String; 
 
  public function initApp():void { 
     mySO = SharedObject.getLocal("mydata"); 
     if (mySO.data.visitDate==null) { 
        welcomeMessage = "Hello first-timer!" 
     } else { 
        welcomeMessage = "Welcome back. You last visited on " + 
           getVisitDate(); 
     } 
  } 
 
  private function getVisitDate():Date { 
     return mySO.data.visitDate; 
  } 
 
  private function storeDate():void { 
     mySO.data.visitDate = new Date(); 
     mySO.flush(); 
  } 
  
  private function deleteLSO():void { 
     // Deletes the SharedObject from the client machine. 
     // Next time they log in, they will be a 'first-timer'. 
     mySO.clear(); 
  } 
  
  ]]></mx:Script> 
  <mx:Label id="label1" text="{welcomeMessage}"/> 
  <mx:Button label="Log Out" click="storeDate()"/> 
  <mx:Button label="Delete LSO" click="deleteLSO()"/> 
</mx:Application>