2012-11-17 44 views
5

我在遊戲中使用SharedObject來存儲玩家在遊戲中的進度(等級分數,解鎖等級)。Air iOS SharedObject更新後被刪除

一切工作正常,但問題是,當我提交了遊戲的更新(具有相同的證書和.swf.ipa相同的文件名)當遊戲更新老SharedObject被刪除,這是遊戲和我的非常大的問題。

遊戲的兩個版本都是用Flash CS 6和Air SDK 3.5製作的。

任何想法爲什麼SharedObject被刪除,我該如何防止?

回答

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

非常感謝,B tw我發現共享對象有什麼問題。由於我使用的是遊戲發行商,因此發佈商公司在上傳它之前已更改.ipa文件的版本和名稱。所以使用Shared Object沒有問題。 –

+0

@MartinGrigorov是否意味着您無法更改IPA的「版本」號以進行更新?我認爲這是一個真正的問題,因爲每次更新IPA並提交給AppStore時都必須增加版本號! –

相關問題