2012-11-17 12 views
5

Tôi đang sử dụng SharedObject giây trong trò chơi để lưu trữ tiến trình của người chơi trong trò chơi (điểm số, cấp độ mở khóa, v.v.).Air iOS SharedObject bị xóa sau khi cập nhật

Mọi thứ đều hoạt động tốt, nhưng vấn đề là khi tôi gửi bản cập nhật trò chơi (có cùng chứng chỉ và cùng tên của các tệp .swf.ipa) khi trò chơi được cập nhật cũ SharedObject bị xóa và đây là vấn đề rất lớn đối với trò chơi và đối với tôi.

Cả hai phiên bản của trò chơi đều được tạo bằng Flash CS 6 và Air SDK 3.5.

Bất kỳ ý tưởng nào tại sao SharedObject bị xóa, làm cách nào để ngăn chặn điều đó?

Trả lời

1

Tôi giả định rằng lý do vì sao SharedObject bị ghi đè là do nó được đóng gói với .ipa trong khi chuyển đổi.

Tôi hiểu rằng sẽ không giúp tình hình hiện tại của bạn bằng cách tận dụng SharedObject nhưng bạn có thể thử sử dụng flash.filesystem để đọc/ghi dữ liệu của mình vào tệp tùy chọn thay vì sử dụng SharedObject trong tương lai.

Dưới đây là lớp lưu trữ mà tôi sử dụng với công việc của riêng mình, nhưng tôi chưa bao giờ phát triển cho iOS trước đây nên tôi không chắc chắn rằng nó sẽ hoạt động như trên các mục tiêu triển khai khác, mặc dù tôi tin là nó nên.

Trường hợp sử dụng:

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

Thanks a lot, b tw Tôi đã tìm thấy vấn đề với các đối tượng chia sẻ là gì. Vì tôi đang sử dụng nhà xuất bản cho trò chơi, công ty nhà xuất bản đã thay đổi phiên bản và tên của tệp .ipa trước khi tải lên. Vì vậy, không có vấn đề gì khi sử dụng Shared Object. –

+0

@MartinGrigorov có nghĩa là bạn không thể thay đổi số phiên bản của IPA để cập nhật không? Tôi nghĩ rằng đó là một vấn đề thực sự, vì bạn phải tăng số phiên bản mỗi khi bạn cập nhật IPA của bạn và gửi cho AppStore! –