【问题标题】:Air iOS SharedObject deleted after updatingAir iOS SharedObject 更新后被删除
【发布时间】:2012-11-06 05:34:12
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: ios actionscript-3 flash air shared-objects


    【解决方案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();
    }
    

    Archive Class

    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;
    }
    

    Archive Event Class

    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");
            }
        }
    }
    

    【讨论】:

    • 非常感谢,顺便说一句,我发现共享对象有什么问题。因为我使用的是游戏发行商,所以发行商公司在上传之前更改了 .ipa 文件的版本和名称。所以使用共享对象是没有问题的。
    • @MartinGrigorov 这是否意味着您不能更改 IPA 的 version 编号以进行更新?我认为这是一个真正的问题,因为每次更新 IPA 并提交到 AppStore 时都必须增加版本号!
    猜你喜欢
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多