2012-11-17 15 views
5

Sto usando SharedObject s nel mio gioco per memorizzare l'avanzamento del giocatore nel gioco (livelli, livelli sbloccati, ecc.).Air iOS SharedObject cancellato dopo l'aggiornamento

Tutto sta funzionando bene, ma il problema è quando ho presentato un aggiornamento del gioco (con gli stessi certificati e gli stessi nomi dei file .swf e .ipa) quando il gioco viene aggiornato il vecchio SharedObject viene eliminato e questo è un grosso problema per il gioco e per me.

Entrambe le versioni del gioco sono realizzate con Flash CS 6 e Air SDK 3.5.

Qualsiasi idea del motivo per cui lo SharedObject è stato eliminato, come posso impedirlo?

risposta

1

Suppongo che il motivo per cui SharedObject venga sovrascritto sia perché è in bundle con .ipa durante la conversione.

Capisco che non aiuterà la situazione attuale con il salvataggio del tuo SharedObject ma potresti provare a utilizzare flash.filesystem per leggere/scrivere i tuoi dati in un file di preferenze invece di utilizzare SharedObject in futuro.

Di seguito è la mia classe di archivio che uso con il mio lavoro, ma non ho mai sviluppato per iOS prima quindi non sono sicuro che funzionerà come su altri obiettivi di distribuzione, anche se credo che dovrebbe.

caso d'uso:

//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

Grazie mille, b tw Ho trovato qual è il problema con gli oggetti condivisi. Poiché sto utilizzando un editore per il gioco, la società editrice ha cambiato la versione e il nome del file .ipa prima di caricarlo. Quindi non c'è alcun problema ad usare l'oggetto condiviso. –

+0

@MartinGrigorov significa che non è possibile modificare il numero 'version' dell'IPA per un aggiornamento? Penso che sia un problema reale, dal momento che devi aumentare il numero di versione ogni volta che aggiorni il tuo IPA e lo sottoponi ad AppStore! –