2012-11-17 8 views
5

Ich verwende SharedObject s in meinem Spiel, um den Fortschritt des Spielers im Spiel zu speichern (Level-Scores, entsperrte Levels, etc.).Air iOS SharedObject gelöscht nach dem Update

Alles funktioniert gut, aber das Problem ist, wenn ich ein Update des Spiels vorgelegt (mit den gleichen Zertifikaten und dem gleichen Namen der .swf und .ipa-Dateien), wenn das Spiel der alten SharedObject aktualisiert wird gelöscht und das ist sehr großes Problem für das Spiel und für mich.

Beide Versionen des Spiels sind mit Flash CS 6 und Air SDK 3.5 gemacht.

Irgendeine Idee, warum die SharedObject gelöscht wird, wie kann ich das verhindern?

Antwort

1

Ich gehe davon aus, dass der Grund, warum SharedObject überschrieben wird, ist, weil es während der Konvertierung mit der .ipa gebündelt ist.

Ich verstehe, dass Ihre aktuelle Situation mit Salvaging Ihr SharedObject nicht helfen wird, aber Sie könnten flash.filesystem verwenden, um Ihre Daten in einer Präferenz-Datei zu lesen/schreiben, anstatt SharedObject in Zukunft zu verwenden.

Unten ist meine Archiv-Klasse, die ich mit meiner eigenen Arbeit verwende, aber ich habe noch nie für iOS entwickelt, also bin ich mir nicht sicher, ob sie auf anderen Implementierungszielen funktioniert, obwohl ich glaube, dass es funktionieren sollte.

Use Case:

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

Vielen Dank, b tw Ich habe gefunden, was das Problem mit den Shared Objects ist. Da ich Publisher für das Spiel verwende, hat das Publisher-Unternehmen die Version und den Namen der .ipa-Datei vor dem Hochladen geändert. Es gibt also kein Problem, Shared Object zu verwenden. –

+0

@MartinGrigorov bedeutet das, dass Sie die Versionsnummer des IPA für ein Update nicht ändern können? Ich denke, das ist ein echtes Problem, da Sie die Versionsnummer jedes Mal aktualisieren müssen, wenn Sie Ihre IPA aktualisieren und an AppStore senden! –

Verwandte Themen