5

SharedObject在我的游戏中使用 s 来存储玩家在游戏中的进度(关卡分数、解锁关卡等)。

一切正常,但问题是当我提交游戏更新(具有相同的证书和相同的文件名.swf.ipa更新游戏时,旧SharedObject的被删除,这对游戏来说是一个很大的问题,为了我。

两个版本的游戏都是用 Flash CS 6 和 Air SDK 3.5 制作的。

知道为什么会SharedObject被删除,我该如何防止呢?

4

1 回答 1

1

我假设 SharedObject 被覆盖的原因是因为它在转换过程中与 .ipa 捆绑在一起。

我知道这不会帮助您挽救您的 SharedObject 目前的情况,但您可以尝试使用flash.filesystem将您的数据读/写到首选项文件,而不是在未来使用 SharedObject。

下面是我在自己的工作中使用的 Archive 类,但我以前从未为 iOS 开发过,所以我不确定它是否会像在其他部署目标上那样运行,尽管我相信它应该。

用例:

//Imports
import com.mattie.data.Archive;
import com.mattie.events.ArchiveEvent;

//Constants
private static const PREF_CANVAS_VOLUME:String = "prefCanvasVolume";
private static const DEFAULT_VOLUME:Number = 0.5;

//Initialize Archive
private function initArchive():void
{
    archive = new Archive();
    archive.addEventListener(ArchiveEvent.LOAD, init);
    archive.load();
}

//Initialize
private function init(event:ArchiveEvent):void
{
    archive.removeEventListener(ArchiveEvent.LOAD, init);

    canvasVolume = archive.read(PREF_CANVAS_VOLUME, DEFAULT_VOLUME);         
}

//Application Exiting Event Handler
private function applicationExitingEventHandler(event:Event):void
{
    stage.nativeWindow.removeEventListener(Event.CLOSING, applicationExitingEventHandler);

    archive.write(PREF_CANVAS_VOLUME, canvas.volume);

    archive.addEventListener(ArchiveEvent.SAVE, archiveSavedEventHandler);
    archive.save();
}

//Archive Saved Event Handler
private function archiveSavedEventHandler(event:ArchiveEvent):void
{
    archive.removeEventListener(ArchiveEvent.SAVE, archiveSavedEventHandler);

    NativeApplication.nativeApplication.exit();
}

档案类

package com.mattie.data
{
    //Imports
    import com.mattie.events.ArchiveEvent;
    import flash.data.EncryptedLocalStore;
    import flash.desktop.NativeApplication;
    import flash.events.EventDispatcher;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.registerClassAlias;
    import flash.utils.ByteArray;

    //Class
    public final class Archive extends EventDispatcher
    {
        //Properties
        private static var singleton:Archive;

        //Variables
        private var file:File;
        private var data:Object;

        //Constructor
        public function Archive()
        {
            if (singleton)
            {
                throw new Error("Archive is a singleton that is only accessible via the \"archive\" public property.");
            }

            file = File.applicationStorageDirectory.resolvePath(NativeApplication.nativeApplication.applicationID + "Archive");

            data = new Object();

            registerClassAlias("Item", Item);
        }

        //Load
        public function load():void
        {
            if (file.exists)
            {
                var fileStream:FileStream = new FileStream();
                fileStream.open(file, FileMode.READ);

                data = fileStream.readObject();

                fileStream.close();
            }

            dispatchEvent(new ArchiveEvent(ArchiveEvent.LOAD));
        }

        //Read
        public function read(key:String, defaultValue:* = null):*
        {
            var value:* = defaultValue;

            if (data[key] != undefined)
            {
                var item:Item = Item(data[key]);

                if (item.encrypted)
                {
                    var bytes:ByteArray = EncryptedLocalStore.getItem(key);

                    if (bytes == null)
                    {                       
                        return value;
                    }

                    switch (item.value)
                    {
                        case "Boolean":     value = bytes.readBoolean();                        break;
                        case "int":         value = bytes.readInt();                            break;
                        case "uint":        value = bytes.readUnsignedInt();                    break;
                        case "Number":      value = bytes.readDouble();                         break;
                        case "ByteArray":           bytes.readBytes(value = new ByteArray());   break;

                        default:            value = bytes.readUTFBytes(bytes.length);
                    }
                }
                else
                {
                    value = item.value;                    
                }
            }

            return value;
        }

        //Write
        public function write(key:String, value:*, encrypted:Boolean = false, autoSave:Boolean = false):void
        {
            var oldValue:* = read(key);

            if (oldValue != value)
            {
                var item:Item = new Item();
                item.encrypted = encrypted;

                if (encrypted)
                {
                    var constructorString:String = String(value.constructor);
                    constructorString = constructorString.substring(constructorString.lastIndexOf(" ") + 1, constructorString.length - 1);

                    item.value = constructorString;

                    var bytes:ByteArray = new ByteArray();

                    switch (value.constructor)
                    {
                        case Boolean:       bytes.writeBoolean(value);          break;                  
                        case int:           bytes.writeInt(value);              break;
                        case uint:          bytes.writeUnsignedInt(value);      break;
                        case Number:        bytes.writeDouble(value);           break;
                        case ByteArray:     bytes.writeBytes(value);            break;

                        default:            bytes.writeUTFBytes(value);
                    }

                    EncryptedLocalStore.setItem(key, bytes);
                }
                else
                {
                    item.value = value;                    
                }

                data[key] = item;

                dispatchEvent(new ArchiveEvent(ArchiveEvent.WRITE, key, oldValue, value));

                if (autoSave)
                {                    
                    save();
                }
            }
        }

        //Remove
        public function remove(key:String, autoSave:Boolean = false):void
        {
            if (data[key] != undefined)
            {
                var oldValue:* = read(key);

                if (Item(data[key]).encrypted)
                {                    
                    EncryptedLocalStore.removeItem(key);
                }

                delete data[key];

                dispatchEvent(new ArchiveEvent(ArchiveEvent.DELETE, key, oldValue));

                if (autoSave)
                {                    
                    save();
                }
            }
        }

        //Contains
        public function contains(key:String):Boolean
        {
            return (data[key] != undefined);
        }

        //Save
        public function save():void
        {
            var fileStream:FileStream = new FileStream();
            fileStream.open(file, FileMode.WRITE);
            fileStream.writeObject(data);
            fileStream.close();

            dispatchEvent(new ArchiveEvent(ArchiveEvent.SAVE));
        }

        //Get Singleton
        public static function get archive():Archive
        {
            if (!singleton)
            {
                singleton = new Archive();
            }

            return singleton;
        }
    }
}

//Item
class Item
{
    //Variables
    public var value:*;
    public var encrypted:Boolean = false;
}

归档事件类

package com.mattie.events
{
    //Imports
    import flash.events.Event;

    //Class
    public class ArchiveEvent extends Event
    {
        //Constants
        public static const LOAD:String = "load";
        public static const WRITE:String = "write";
        public static const DELETE:String = "delete";
        public static const SAVE:String = "save";

        //Properties
        public var key:String;
        public var oldValue:*;
        public var newValue:*;

        //Constructor
        public function ArchiveEvent(type:String, key:String = null, oldValue:* = null, newValue:* = null) 
        {
            super(type);

            this.key = key;
            this.oldValue = oldValue;
            this.newValue = newValue;
        }

        //Clone
        public override function clone():Event
        {
            return new ArchiveEvent(type, key, oldValue, newValue);
        }

        //To String
        public override function toString():String
        {
            return formatToString("ArchiveEvent", "type", "key", "oldValue", "newValue");
        }
    }
}
于 2012-11-18T15:59:37.303 回答