ADOBE/ ActionScript

[AS] 액션스크립트 SharedObject 쿠키와 비슷하게 저장 제어 관련

AlrepondTech 2020. 9. 22. 00:04
반응형

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

출처: http://rinn.kr/18

SharedObject 를 사용해서 로컬에 데이터 저장하기

SharedObject를 간단하게 이야기 하면 웹브라우저의 쿠키와 비슷하게 개발자가 원하는 데이터를 로컬에 저장하는 객체이다.

개별 유저에 커스터마이징된 화면이라던지, 이전에 방문했었는지의 여부 라던지.. 개발자가 필요에 의해서 데이터를 저장해야 하는 경우에 사용할 수 있다. 

쿠키는 String 데이터만을 가지는데 반해 SharedObject 는 Array, Object 등 복합데이터를 저장할 수 있기 때문에 활용가능성이 무궁무진하다. 
(단 메서드는 저장할 수 없다 -ㅅ-)

기본 용량은 100K 이고 저장할 공간의 크기를 늘이거나 줄일 수 있다. 저장하는 데이터의 크기가 정해져 있다면 굳이 크게 할 필요는 없는거니 상황에 맞춰서 적용하면 되겠다. 

100K를 넘는 용량을 지정하게 되면 사용자에게 저장하는 것을 허용할 것인지 여부를 묻는 대화상자가 나오게 되는데 아니오 해버리면 사용하지 못하는 상황이 와버리니 주의해서 사용하면 된다. 

기본적으로 도메인 기준으로 공유할수 있다. 쿠키처럼 다른 도메인에서 만들어진 SO는 읽을수 없고 같은 도메인에서 만들어진 SO파일만 읽을 수 있다. 

만들어지는 파일은 *.sol 확장자를 가지게 되고.. 저장되는 경로는 운영체제 시스템에 따라 다르고 윈도우의 경우는
C:/Document and Setting/계정이름/Application Data/Macromedia/FlashPlayer 하위에 저장이 된다.

var so:SharedObject = SharedObject.getLocal("mySo")

형식으로 불러와서 쓸수 있다
기본적으로 Object 처럼 key value 형식으로 저장을 하게 되고 data 속성을 통해서 내부의 값들을 가져올 수 있다.

공유객체를 읽어오도록 하면 SharedObject객체가 존재 할때는 data 를 읽어오고 데이터가 없으면 새로운 객체를 생성하게 된다. 

간단하게 예제를 보면서 확인 해보자.




SharedObject 데이터가 있다면 userName 과 description 에 값이 나온다.
없는경우 왼쪽에서 값을 입력하고 createSo 버튼을 누르면 생성된다.

오른쪽에서 key 텍스트 필드에 "userName" 이나 "description", "rinn" 이라고 입력하고 getSO 버튼을 누르면 아래의 필드에 값이 표시된다.

리프레시 해보면 왼쪽 필드가 채워져서 swf가 로딩될것이다.

스크립트 부분의 소스이다.

import mx.controls.Alert;

private
var so: SharedObject;

private
function init(): void

{

    so = SharedObject.getLocal("mySo");

    if (so.data.userName == undefined)

        Alert.show("ShareObject가 정의되어있지 않습니다");

    else

    {

        txtUserName.text = so.data.userName;

        txtDescription.text = so.data.description;

    }

}

private
function createSo(): void

{

    setSo("userName", txtUserName.text);

    setSo("description", txtDescription.text);

    var ar: Array = [];

    ar.push("http://rinn.kr");

    ar.push("rinn@naver.com");

    setSo("rinn", ar);

}

private
function clearSo(): void

{

    so.clear();

    txtUserName.text = txtDescription.text = "";

}

private
function setSo(key: String, data: * ): void

{

    so.data[key] = data;

}

private
function getSo(key: String): *

{

    if (so.data[key] == undefined)

    {

        Alert.show(key + " 는 정의되어있지 않습니다");

    }

    return so.data[key];

}

 

 

createSo 함수에서 보면 저장할 수 있는 데이터가 여러가지 형식이 가능하기 때문에 활용범위가 넓다.

기본적으로 페이지의 이동이나 브라우저가 닫힐때 저장을 하게 되는데 필요할때 즉시 저장하기 위해서는 so.flush() 를 사용하면 된다.
삭제하기 위해서는 so.clear()를 사용한다.

더 자세한 메서드는 레퍼런스 (http://livedocs.adobe.com/flex/3/langref/flash/net/SharedObject.html)를 참조하면 된다.

 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://help.adobe.com/ko_KR/FlashPlatform/reference/actionscript/3/flash/net/SharedObject.html

 

data

속성  

data:Object  [읽기 전용]

언어 버전:  ActionScript 3.0
런타임 버전:  AIR 1.0, Flash Player 9, Flash Lite 4

객체의 data 속성에 할당된 특성 모음입니다. 이러한 특성은 공유 및 저장이 가능합니다. 각 특성은 Array, Number, Boolean, ByteArray, XML 등 어떤 ActionScript 또는 JavaScript 유형의 객체도 될 수 있습니다. 예를 들어 다음 예제는 공유 객체의 다양한 속성에 값을 지정합니다.

   var items_array:Array = new Array(101, 346, 483);
     var currentUserIsAdmin:Boolean = true;
     var currentUserName:String = "Ramona";
     
     var my_so:SharedObject = SharedObject.getLocal("superfoo");
     my_so.data.itemNumbers = items_array;
     my_so.data.adminPrivileges = currentUserIsAdmin;
     my_so.data.userName = currentUserName;
     
     for (var prop in my_so.data) {
       trace(prop+": "+my_so.data[prop]);
     }

공유 객체가 영구적이면 data 속성의 모든 특성이 저장되고, 이 공유 객체에는 다음 정보가 포함됩니다.

  userName: Ramona
     adminPrivileges: true
     itemNumbers: 101,346,483
     

참고: 공유 객체의 data 속성에 직접 값을 할당하지 마십시오(예: so.data = someValue). 이러한 할당은 무시됩니다.

로컬 공유 객체의 특성을 삭제하려면 delete so.data.attributeName과 같은 코드를 사용합니다. 로컬 공유 객체의 특성을 null 또는 undefined로 설정해도 특성이 삭제되지는 않습니다.

공유 객체에 대하여 전용 값, 즉 객체가 사용 중인 동안 클라이언트 인스턴스에만 사용할 수 있으며 객체가 닫힐 때 객체와 함께 저장되지 않는 값을 작성하려면 다음 예제와 같이 값을 저장할 속성을 작성할 때 data라는 이름을 붙이지 않습니다.

  var my_so:SharedObject = SharedObject.getLocal("superfoo");
     my_so.favoriteColor = "blue";
     my_so.favoriteNightClub = "The Bluenote Tavern";
     my_so.favoriteSong = "My World is Blue";
     
     for (var prop in my_so) {
       trace(prop+": "+my_so[prop]);
     }

공유 객체에는 다음 데이터가 포함됩니다.

  favoriteSong: My World is Blue
     favoriteNightClub: The Bluenote Tavern
     favoriteColor: blue
     data: [object Object]

서버와 함께 사용된 원격 공유 객체의 경우 data 속성의 모든 특성을 공유 객체에 연결된 모든 클라이언트가 사용할 수 있습니다. 객체가 영구적일 경우 모든 특성은 저장됩니다. 한 클라이언트가 특성 값을 변경하면 모든 클라이언트는 새로운 값을 보게 됩니다.

구현 
    public function get data():Object

관련 API 요소

 

getLocal()

defaultObjectEncoding

속성  

 

defaultObjectEncoding:uint

언어 버전:  ActionScript 3.0
런타임 버전:  AIR 1.0, Flash Player 9, Flash Lite 4

SWF 파일에서 만들어진 모든 로컬 공유 객체에 대한 기본 객체 인코딩(AMF 버전)입니다. 로컬 공유 객체가 디스크에 기록될 때 SharedObject.defaultObjectEncoding 속성은 ActionScript 3.0 형식(AMF3) 또는 ActionScript 1.0이나 2.0 형식(AMF0) 중 어떤 Action Message Format 버전을 사용해야 할지를 나타냅니다.

로컬 및 원격 공유 객체 인코딩의 차이점을 비롯하여 객체 인코딩에 대한 자세한 내용은 objectEncoding 속성의 설명을 참조하십시오.

SharedObject.defaultObjectEncoding의 기본값은 ActionScript 3.0 형식인 AMF3을 사용하는 것으로 설정됩니다. ActionScript 2.0이나 1.0 SWF 파일에서 읽을 수 있는 로컬 공유 객체를 써야 할 경우, 로컬 공유 객체를 만들기 전에 스크립트 시작 부분에서 SharedObject.defaultObjectEncoding을 flash.net.ObjectEncoding.AMF0으로 설정하여 ActionScript 1.0 또는 ActionScript 2.0 형식을 사용하게 합니다. 이후로 만들어지는 모든 로컬 공유 객체는 AMF0 인코딩을 사용하며 기존의 컨텐츠와 상호 작용할 수 있습니다. 로컬 공유 객체가 만들어진 후에는 SharedObject.defaultObjectEncoding을 설정하여 기존 로컬 공유 객체의 objectEncoding 값을 변경할 수 없습니다.

SWF 파일에서 만들어진 모든 공유 객체를 대상으로 하지 않고 객체별로 객체 인코딩을 설정하려면 로컬 공유 객체의 objectEncoding 속성을 대신 설정합니다.


구현 
    public static function get defaultObjectEncoding():uint
    public static function set defaultObjectEncoding(value:uint):void

관련 API 요소

 

objectEncoding 속성
ObjectEncoding 클래스

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://blog.naver.com/PostView.nhn?blogId=omangco&logNo=120133574960

 

이 강좌는 액션스크립트 3.0 강좌 입니다.

 

강좌 5. AS3.0에서의 SharedObject

SharedObject는 '플래시 쿠키' 라고도 불리우며 플래시에서 만들어진 데이터를 사용자에 하드 디스크에 저장하는 역할을 합니다.

 

웹에서 사용자의 입력값을 저장해 둘 때에도 쓰이고 플래시 게임같은 경우에는 사용자의 데이터를 저장하는 역할도 합니다.

 

 

1. 어떻게 사용할까?

SharedObject의 사용법은 기본적으로 AS2.0에서의 사용법과 흡사합니다.

(관련 포스트 - http://blog.naver.com/omangco/120116371862)

우선 SharedObject를 사용할 객체를 만듭니다.

var save:SharedObject = SharedObject.getLocal("savedata")

 

주의해야 할 점은 SharedObject는 인스턴스화 시킬 수 없습니다. 즉 아래와 같은 구문은 에러를 일으킵니다.

var save:SharedObject = new SharedObject() // 컴파일 에러 발생

 

또한 메서드가 setLocal이 아닌 getLocal로 되어있는데 어도비 도움말을 참조해 보면 저 과정은 플래시가 "savedata"라는 이름을 가진 파일과 연결을 시도하는 것 입니다. 그리고 여기에서 값을 찾을 수 없을 경우에 "savedata"라는 이름으로 새로운 파일을 생성하게 됩니다.

여기에서 "savedata"는 데이터를 저장할 실제 파일명입니다. 보시다시피 String 타입으로 입력을 받습니다.

또한 name외에도 몇가지 파라미터가 더 있으나 여기에서는 다루지 않으니 어도비 도움말을 참조하세요.

 

2. 데이터를 저장해 보자!

이제 SharedObject 객체를 만들었으니 그 속에 데이터를 담아 볼 차례 입니다. 데이터를 담는 방법은 매우 간단합니다. 위에서 선언된 save를 이용해 봅시다.

save.data.a = 1

 

이러한 구조로 세이브 데이터를 입력 받습니다. a라는 이름은 임의의 이름으로 변수 이름 선언 규칙만 지켜서 쓴다면 어떠한 이름도 사용할 수 있습니다.

그리고 데이터 값을 담는데 여기서 주의해야 할 점은 데이터의 값으로는 원시데이터만 들어갑니다.

(원시 데이터 : int, uint, Number, String, Boolean, null, undefined)

 

Object 같은 객체를 SharedObject를 통해 넣을려 시도를 하면 에러는 발생하지 않지만 나중에 확인해 보면 Object 타입 대신 undefined가 들어가 있습니다.

 

또한 데이터를 넣을때는 배열을 통해서도 넣을 수 있습니다. 배열의 값 역시 원시데이터 값만 들어갈 수 있습니다. 아래는 배열을 통해 SharedObject에 값을 넣는 예제 입니다.

var save:SharedObject = SharedObject.getLocal("test")

var arr:Array = [10, 10+12, new Sprite, "RedHood", false]

save.data.arr = arr

그리고 다시 데이터를 불러오면 아래와 같은 값을 얻게 됩니다.

[10, 22, undefined, "RedHood", false]

이런식으로 저장된 데이터는 플래시 플레이어가 끝날때 외부에 파일로 만들어 집니다.

 

3. 저장을 했으니 불러와야지?

불러오는 과정 역시 어렵지 않습니다. getLocal을 통해 연결에 성공했다면 언제든 저장된 데이터 값을 가져올 수 있습니다.

아래와 같은 구조로 사용합니다.

var num:Number = save.data.a

세이브를 거꾸로 뒤집은거라고 보시면 됩니다. 아래의 예제처럼 변수에 대입하지 않고도 사용할 수 있습니다.

 

if(save.data.bool == false){}

 

또한 이름이 지정되어있지 않은 데이터 값도 로드를 시도할 수 있습니다. 이러할 경우에는 로드된 값은 undefined가 됩니다.

4. 바로 저장하기! flush() 메서드

만약 어떤 사람이 rpg게임을 20시간동안 했다고 가정합시다. 이 사람은 20시간동안 플래시를 한번도 끄지 않고 진행을 해 왔습니다. 그리고 드디어 대망의 라스트 보스를 처치하고 자축을 하는 도중에 컴퓨터가 정전이 되었습니다. 컴퓨터를 재부팅하여 다시 로드를 시도해 보았으나 데이터가 저장이 되어있지 않았고 20시간동안 노력한것이 허사가 되었습니다.

SharedObject는 플래시 플레이어가 안정적으로 종료될때 저장된 데이터 파일을 교체합니다. 하지만 위와 같이 정전등의 이유로 안정적으로 종료가 되지 않았을 경우 SharedObject의 데이터는 저장이 되지 않을 수도 있습니다.

이러한 경우를 방지하기 위해서 flush라는 메서드가 있습니다.

 

이는 특정한 경우에 호출이 되서 지금까지의 SharedObject를 업데이트 하는 메서드 라고 볼 수 있습니다. 아래와 같이 사용합니다.

save.flush()

사용법이 매우 간단하니 세이브 작업이 다 끝나면 무조건 한번씩 돌아가게끔 스크립트를 짜 주는게 좋습니다.

또한 웹에 올릴 경우에는 이 flush 메서드가 없으면 저장이 제대로 안되는 경우도 있습니다. 즉 웹에 사용하는 것이라면 이 flush 메서드는 필수 입니다.

지금까지 간단하게 SharedObject에 대해 알아 보았습니다. 위 4개만 잘 사용해도 큰 문제는 없습니다만 보다 자세한 정보가 필요하다 생각될 경우엔 어도비 도움말을 참조하세요

 

http://help.adobe.com/ko_KR/FlashPlatform/reference/actionscript/3/flash/net/SharedObject.html

 

 

 

=================================

=================================

=================================

 

 

 

 

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

 

A big part of what makes Apple iOS such a great mobile platform is its user interface. Whether you are developing natively or with Adobe Flash Professional CS5.5, users of iOS devices expect you—the application developer—to make your application fit in with the existing iOS experience. An essential part of that experience is interruptibility: your Adobe AIR application needs to save its state frequently and automatically so that it can be switched automatically as users expect—and as Apple specifies in its iPhone Human Interface Guidelines.

This article presents some strategies for saving your application state on iOS devices. The basic capabilities of iOS devices are covered, as well as application design techniques to help give a seamless user experience. I also provide code that demonstrates different techniques for saving state.

Considering state issues

The Apple iOS runs only a single user application at a time to keep the device responsive. Whenever the user launches another application, or an outside event like a phone call occurs, your application can be terminated. This can lead to frustrations for the user: imagine if you were writing a text message or e-mail and a phone call came in and you lost your work! Because of this, it is essential that your application save its state regularly and automatically.

My colleagues and I at PushButton Labs developed a game called Trading Stuff in Outer Space for the iPhone last year using the Flash Professional CS5 (see Figure 1). It is a simple space-based trading game that was developed in eight days to explore the technology. One of the goals of the project was to provide an experience indistinguishable from any other iPhone game. As a result, we had to figure out how to make saving state work.

 

Figure 1. Trading Stuff in Outer Space game screen

Saving state on iOS devices

We envisioned the scenario of applications that lose data when they are interrupted. Of course, the built-in iOS apps don't do that—when you go back to your text messages after that interrupting phone call, you pick up right where you left off. This is done by the simple expedient of saving state when the application is ordered to quit by the OS. In the Objective-C world, you will have to implement this yourself (see the appropriate section of the iOS Application Programming Guide), and it is no different when you are developing with Flash.

Saving on exit

How do you know when to save in Flash? Since AIR applications for iOS share the same API as AIR apps for Adobe AIR, you can listen for the NativeApplication.EXITING event to know when to save your state:

package
{
    import flash.desktop.NativeApplication;
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class Save1 extends Sprite
    {
        public function Save1()
        {
           // Listen for exiting event.
           NativeApplication.nativeApplication.addEventListener(Event.EXITING, onExit);
           
           // Load data.
           load();
        }
        
        private function onExit(e:Event):void
        {
           trace("Save here.");
        }
 
        private function load():void
        {
           trace("Load here.");
        }
 
    }
}

Saving on important events

However, you should also save after crucial events or after a certain interval has passed. For Trading Stuff in Outer Space, crucial events include whenever the player trades (since it is an action that takes a lot of thought and has major effects on gameplay), when the player arrives at a planet, and whenever the player starts or ends a game. For an interval, we chose a period of 30–60 seconds, so that the user would never lose more than a minute's playtime. We chose that threshold because we felt that it was high enough to allow responsive play but low enough to avoid infuriating a user if something causes saving-on-exit to fail.

Unfortunately, the EXITING event isn't 100% reliable. It doesn't always get fired—sometimes due to time limits in the OS, sometimes due to other causes. Your application may crash (although it's unlikely), in which case the normal exiting behavior won't happen. So what we did was to save after every major operation the user performed, as well as approximately once a minute. That way even if users did manage to quit without the application saving state, it was unlikely they would lose more than few seconds of work:

package
{
    import flash.desktop.NativeApplication;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.utils.setInterval;
    
    public class Save2 extends Sprite
    {
        public function Save2()
        {
           // Listen for exiting event.
           NativeApplication.nativeApplication.addEventListener(Event.EXITING, onExit);

           // Also save every 30 seconds.
           setInterval(save, 30*1000);
           
          // Load data.
           load();
        }
        
        private function onExit(e:Event):void
        {
           save();
        }
        
        private function save():void
        {
           trace("Save here.");
        }
 
        private function load():void
        {
           trace("Load here.");
        }
    }
}

General applicability

The issues facing an AIR app on iOS devices are not that different from those facing SWF content in the browser. Users' browsers might crash or users might (accidentally or on purpose) navigate away from the page. Even desktop users may want their applications to always be stateful. You can use the same saving code to enhance the user experience on the web, devices, and the desktop.

Methods for saving

You can save your state in two main ways with AIR applications on iOS devices. One is with an LSO (local SharedObject). As you know, SharedObject.getLocal() (see the documentation) can be used to store data locally. This is convenient for a variety of reasons, not least of which is that you can use AMF to store object graphs:

private function save():void
  {
      // Get the shared object.
      var so:SharedObject = SharedObject.getLocal("myApp");
 
      // Update the age variable.
      so.data['age'] = int(so.data['age']) + 1;
      
      // And flush our changes.
      so.flush();
      
      // Also, indicate the value for debugging.
      trace("Saved generation " + so.data['age']);
  }
 
  private function load():void
  {
      // Get the shared object.
      var so:SharedObject = SharedObject.getLocal("myApp");
 
      // And indicate the value for debugging.
      trace("Loaded generation " + so.data['age']);
  }

In the end, serializing objects directly worked against us in this game application. Depending on your application, using SharedObject might be a perfect fit. For Trading Stuff, I had a lot of complex interrelated data to store, and I also wanted to segregate game state into frequently changed and infrequently changed elements, so using LSOs wasn't a good fit. More on that next.

Saving using file objects

The other approach is to use File objects directly. You can write asynchronously in order to avoid disrupting the frame rate. If different parts of the game state change at different frequencies, you can store them in separate files so that only what actually changes is touched. You have to do your own serialization, but this isn't as bad as it sounds. (You can even use readObject() and writeObject() to store a whole object at once, although this can cause problems in some cases.)

public var age:int = 0;
 
  /**
   * Get a FileStream for reading or writing the save file. 
   * @param write If true, we will write to the file. If false, we will read.
   * @param sync If true, we do synchronous writes. If false, asynchronous.
   * @return A FileStream instance we can read or write with. Don't forget to close it!
   */
  private function getSaveStream(write:Boolean, sync:Boolean = true):FileStream
  {
      // The data file lives in the app storage directory, per iPhone guidelines. 
      var f:File = File.applicationStorageDirectory.resolvePath("myApp.dat");
      
      if(f.exists == false)
          return null;
      
      // Try creating and opening the stream.
      var fs:FileStream = new FileStream();
      try
      {
         // If we are writing asynchronously, openAsync.
          if(write && !sync)
             fs.openAsync(f, FileMode.WRITE);
          else
         {
             // For synchronous write, or all reads, open synchronously.
             fs.open(f, write ? FileMode.WRITE : FileMode.READ);
         }
      }
      catch(e:Error)
      {
         // On error, simply return null.
          return null;
      }
      return fs;
  }
  
  private function load():void
  {
      // Get the stream and read from it.
      var fs:FileStream = getSaveStream(false);
      if(fs)
      {
          try
          {
             age = fs.readInt();
             fs.close();
          }
          catch(e:Error)
          {
             trace("Couldn't load due to error: " + e.toString());
          }
      }
      
      trace("Loaded age = " + age);
  }
  
  private function save():void
  {
      // Update age.
      age++;
      
      // Get stream and write to it – asynchronously, to avoid hitching.
      var fs:FileStream = getSaveStream(true, false);
      fs.writeInt(age);
      fs.close();
      
      trace("Saved age = " + age);
  }

Both of these should be straightforward to understand. If you've done Flash or AIR development, you've almost certainly dealt with either SharedObject or File. If not, you might want to refer to their documentation for details and examples.

You can also use readObject() and writeObject() to store or retrieve an object from a File object. This is powerful and saves you from a lot of repetitive serialization code. However, if you aren't careful, it can introduce problems: for instance, saving a DisplayObject won't work due to the various helper objects and complex relationships involved. Even saving pure data classes can be risky because they may have references to other objects that you don't want to serialize.

Saving the state of your whole application is, of course, more involved. I discuss this issue next.

State management architecture

The larger issue I ran into was serializing all my application data. Figuring out where to write is easy, but figuring out what to write is a little trickier. Naturally, because I am a programmer, I wanted to do it with as little work as possible.

The first thing I tried was directly serializing parts of my DisplayObject hierarchy and game state via AMF in a SharedObject. This was attractive initially because I figured I could throw references to a few key parts of my application into the SharedObject and be done. However, this didn't work: DisplayObjects have lots of helper objects with strange construction restrictions that are not AMF-friendly. It also led to uncontrolled serialization, where the object I was serializing contained a reference to other objects that ended up bringing in most of my application—and I didn't want to waste time debugging issues from strange dangling objects being serialized.

So, instead, I switched to use the File save() method. This meant I had to write some code to load and save objects that made up the state of my application. Up front, this involved more lines of code, but since they were direct and simple—and I did not plan on modifying the application much past launch—this approach ended up being much quicker to write and debug than the fewer lines of code that would be required for a more automatic solution.

The following code snippet shows what saving and loading looks like for the user's current waypoint:

// Serialize current waypoint.
gfs.writeInt(currentWaypointIndex);
gfs.writeBoolean(wayPoint != null);
if(wayPoint != null)
{
    gfs.writeFloat(wayPoint.x);
    gfs.writeFloat(wayPoint.y);
}
 
// Load waypoint state.
currentWaypointIndex = gfs.readInt();
if(gfs.readBoolean())
{
    wayPoint = new Point();
    wayPoint.x = gfs.readFloat();
    wayPoint.y = gfs.readFloat();
}
else
{
    wayPoint = null
}

As you can see, the serialization code has to allocate objects when appropriate; it has to detect if variables are null, and note that in the file; and it has to write each field with the right type. This can be a little overwhelming at first, but with a little practice you'll quickly realize that you are reusing a small set of common idioms for nearly every task.

I also made a singleton to manage all my game state. It kept track of the player's inventory, the locations of everything in the universe, the status of enemies, progress with missions, and so forth. From this singleton, I had methods to reset the game's state, to write it, and to read it back again. In some cases (such as inventory or missions) the state was owned by the singleton. In other cases (such as positions of game objects like the player and planets) the state is managed elsewhere, by other objects, but the singleton can get to it for saving purposes. On top of this foundation, it was easy to implement various saving strategies, as mentioned previously.

Where to go from here

 

Saving state is a key part of making your content fit smoothly into the iOS experience. Since only one application at a time can currently run on iOS devices, it's important to store not only the user's data, but the state of your application's UI. It's not a difficult detail, but it is an important one. I hope this article has helped you understand the key pieces involved in implementing this important functionality in your own application.

Saving state is a broad topic; there's no one-size-fits-all solution. A quick overview of the many different options for serialization can be found in the Serialization entry on Wikipedia. Flash natively supports XML (see Colin Moock's book,Essential ActionScript 3, for several great chapters on XML and E4X) and AMF, which are good building blocks for your serialization needs. There are also libraries like as3corelib that add support for JSON and other serialization formats. Of course, when you're saving application state between runs, what matters most is that the technology you choose is simple, easy to work with, and reliable.

From here, you might want to take the sample code included with this article and try to integrate it with your own content. There are a few decision points, such as using local SharedObjects or File objects, or saving frequently vs. infrequently. Make sure to run a few tests before deciding one way or the other; informed decisions are always best, and the information you need will depend on your specific application. Once you have a solution, test it by frequently quitting in the middle of your program's execution. It might not be possible to restore every piece of state exactly, but with surprisingly little work you will get close enough so that users accept your application as part of their positive iOS device experience.

Check out this series of articles to help you learn more about developing for iOS using Flash Professional:

 

 

=================================

=================================

=================================

 

 

반응형