Skip to main content
marchbold
Inspiring
October 24, 2018
Question

Read SharedObject directly from sol file (Android)

  • October 24, 2018
  • 3 replies
  • 2884 views

Made a bit of an error in a recent release of an Android app and accidentally changed the name of the swf that was packaged with the app. (We upgraded this project from FB to IntelliJ and ignored the output name change.)

It seemed fine in testing however we use a SharedObject in this app to store some user data and I hadn't realised that a SharedObject is stored in a path containing the name of the swf:

#SharedObjects/app.swf/objectname.sol

So the name change to swf meant that our users are losing their data when upgrading the app.

#SharedObjects/app_new.swf/objectname.sol

I was hoping to be able to do a new update and merge the two objects, but I can't seem to load the old data with SharedObject.

Does anyone know how to read the .sol format directly? Is there a library available anywhere?

I can access the file in the old path but I'm hoping I don't have to write a parser.

This topic has been closed for replies.

3 replies

Guillaume DOWiNO
Participant
September 29, 2020

Hi Michael,

I also need to read some older sharedobject for an app I'm porting to another technology than AIR AS3, but I never find somewhere the path where are saved the shared object localy on Android and iOS. Do you know this ?
You write "#SharedObjects/xxx" where have you found this ?

 

Regards,

marchbold
marchboldAuthor
Inspiring
October 4, 2020

From memory I was just doing a directory listing on the device and inspecting the files in the application storage directory. 

air native extensions // https://airnativeextensions.com
Inspiring
October 26, 2018

if you want to parse manually, the format is about

header - 16 bytes

  |_ magic:      00 BF       - 2 bytes - readUnsignedShort()

  |_ LSO length: 00 00 04 59 - 4 bytes - readUnsignedInt()

  |_ TCSO:       54 43 53 4F - 4 bytes - readUnsignedInt()

  |_ padding:    00 04 00 00 00 00 - 6 bytes - readUnsignedInt() + readUnsignedShort()

data

  |_ LSO name:   ...               - VA bytes - readUTF()

  |_ padding:    00 00 00 00       - 4 bytes - readUnsignedInt()

  |_ data:       ...               - N bytes (AMF0) eg. be sure to use ObjectEncoding.AMF0

or if you want more control you can look into this project, there is an AS3 class AMF0

cvlib

marchbold
marchboldAuthor
Inspiring
October 26, 2018

zwetan_uk​ Gotten exactly that far already myself Though the padding in your "data" block is actually the AMF version, and will be 3 for newly created SharedObjects (AMF3).

data

|_ LSO name length: 2 byte short  readUnsignedShort

|_ LSO name bytes: readUTFBytes

|_ AMF version: readInt

|_ data ...

I was hoping to use the ByteArray.readObject function to read the AMF data block at the end, but it's not working, keeps throwing range errors. The data definitely is there, though looks slightly different from what I've read about AMF data, but not sure if I just don't understand the AMF data format.

Have you got a copy of that cvlib? Doesn't seem to be on Google Code any more? Hoping I don't have to write an AMF parser as well.

ASWC​ Isn't SQLite still stored in a file in the application storage? So the user can just as easily delete that as a shared object? Definitely agree that SharedObjects aren't the best solution for storage though.

air native extensions // https://airnativeextensions.com
marchbold
marchboldAuthor
Inspiring
October 27, 2018

zwetan_uk​ I found a copy, thanks.

Definitely looks as though the format in the SharedObject is a variant on the AMF standard object encoding, but I've got it extracting what I need now.

air native extensions // https://airnativeextensions.com
natural_criticB837
Legend
October 24, 2018

Have you tried to create a second .swf with the old name and load it into your main.swf to see if that one can load the old SharedObject, while the main swf (new name) accesses the new SharedObject?

I have no info about the .sol format. But in case no one can help, here is another idea: You could try and release a new version that copies all the user data from the new SharedObject to some other persistence storage, e.g. a local database or your own file format. Then one week later you release another update to access the old SharedObject and merge into it all the data that exists in the local database / your own file format. That way you quickly revert the broken change and also maintain the data that has been stored since the rename has occured for most of your users. (All that started the app during that week)

marchbold
marchboldAuthor
Inspiring
October 25, 2018

Good idea, but that method would involve ensuring everyone updated through both versions right? Anyone who skipped one of the versions would lose data?

Think I'm going to have to bite the bullet and write an as3 sol parser.

air native extensions // https://airnativeextensions.com
natural_criticB837
Legend
October 25, 2018

Yes, this would only work for those people that start the app at least once for each update, so you would definitely lose data for a portion of the users. Depending on the kind of data (preferences vs progress data for example) this might be acceptable or not. We have been using this approach in the past when migrating from one local storage type to another, but over periods of several months and only for preference / login data that is not catastrophic to lose.