问题
As the title states, my user's on iOS and Android are reporting their save data has been deleted when I push an update to the respected storefronts. The game saves and restores data properly on application load and exit. I have not changed any save information locations or package names... Just mere bug fixes, build, push.
Any clarification would be helpful, or proposed redundant data backup scheme's I should pursue to ensure the end-user experience is from henceforth not affected negatively. I would also like to understand better how I can test this as a release package is not allowed to update a market installed application.
var so:SharedObject = SharedObject.getLocal("storage");
var u:User;
if(so.data != null){
u = so.data.user;
}
trace("Loading application...");
if(u != null){
trace("LOADING SAVE DATA");
user = u;
}else{
trace("NO SAVE DATA EXISTS");
user = new User();
}
回答1:
I have discovered the cause of this issue and it seems that Adobe has identified and fixed the issue as well (as of AIR 3.5). https://bugbase.adobe.com/index.cfm?event=bug&id=3347676
SharedObjects are stored within a directory named according to the SWF used by your application, so if your application is running off "myApp.swf" the SharedObject will be stored in a directory "myApp". If you change the name of this SWF (i.e. the corresponding XML build sheet configuration file for your AIR project) any subsequent builds will store their SharedObjects in a new location.
The issue described in this bug was specifically denoted for iOS, wherein the application was not storing the SharedObject in the corresponding SWF location as described above but in a separate location denoted by the "filename" attribute in your project's XML build sheet.
I have also discovered that Adobe does indeed condone the use of a SharedObject for persistent storage on a mobile platform.
I have developed a simple backup for future version save redundancy in case future updates fail to persist the SharedObject.
/** the last timestamp a deep save was completed */
private var mLastSave:Number = -1;
/**
* save the state of the globals object and all of its
* sub objects.
* @warning
* all objects must implement variables in a "public" state.
* Private variables are not saved within the persistance manager
*/
public function save():void{
var so:SharedObject = SharedObject.getLocal("storage");
so.data.user = user;
so.flush();
saveDeep();
}
/**
* Save the SharedObject to denoted mobile applicationStorageDirectory.
*/
public function saveDeep():void{
// save on first application save or after
// every 5 minutes
if(mLastSave == -1 || mLastSave < getTime() + 300000){
mLastSave = getTime();
var file:File = File.applicationStorageDirectory.resolvePath("userSave");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
var ba:ByteArray = new ByteArray();
ba.writeObject(user);
fileStream.writeBytes(ba);
fileStream.close();
}
}
/**
* Load the application from the SharedObject be default
* if the SharedObject DNE attempt to load from the
* applicationStorageDirectory, if neither exist
* create new User object
*/
public function load():void{
registerClassAlias("user", User);
// Create/read a shared-object named "userData"
var so:SharedObject = SharedObject.getLocal("storage");
var u:User;
if(so.data != null){
u = so.data.user;
}
trace("Loading application...");
if(u != null){
trace("LOADING SAVE DATA");
user = u;
}else{
trace("NO SAVE DATA EXISTS");
var file:File = File.applicationStorageDirectory.resolvePath("userSave");
if(file.exists){
trace("Found userSave backup -attempting to load");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var ba:ByteArray = new ByteArray();
fileStream.readBytes(ba);
fileStream.close();
try{
user = (ba.readObject() as User);
}catch( e : EOFError ){
trace("SharedObject did not exist, attempted userSave load, failed");
}
}else{
user = new User();
trace("created New user...");
}
}
}
来源:https://stackoverflow.com/questions/16737843/adobe-air-sharedobject-android-ios-on-update-not-found