AS3: Save/Load Player data in loaded SWF Files - actionscript-3

So I have a Main .Fla/.SWF File which contains buttons to load in external SWF files using a LoadSWF class.
My Main class save/load code is:
private function saveData(): void {
// savedData can now take any number of properties of any type
// playerGameData is the variable name in which data is saved
savedGameData.data.savedPlayerData = playerData;
savedGameData.flush();
loadData();
tracePlayerData();
}
private function loadData(): void {
// gets the data stored in the SharedObject
playerData = savedGameData.data.savedPlayerData;
}
Assuming a set of saved data can be traced as: trace("Player Name:", playerData.playerName);
How can I load in the saved data, "playerData.playerName" into one of my externally loaded SWF files, so I can give a personalized message such as msgDisplay.text = playerData.playerName + "You Win!"

What you want to do is to pass data from a swf to another.
The simplest way to do it is to pass them using the URL parameters, for instance :
swf2.swf?params=lol
You can pass JSON or such inside that types of parameters, so you'll be able to pass full objects with any number or property.
Document yourself on how to generate, parse, and send json through URL parameters.

Related

Xamarin Forms - Saving object to access it later

I am using Xamarin Forms with Newtonsoft.JSON and Xam.Plugin.Settings plugins to save IDevice object as JSON to use it later.
First page:
private async void SelectBluetoothDevice(object sender, SelectedItemChangedEventArgs e)
{
string device = JsonConvert.SerializeObject((IDevice) e.SelectedItem);
AppSettings.AddOrUpdateValue("device", device);
await Navigation.PopAsync();
}
Here I simply make selected item to JSON string and save it. It works like it should be.
But the problem im facing comes whenever I try to deserialize from saved string.
string device = AppSettings.GetValueOrDefault("device", "");
if (!device.Equals(""))
{
Debug.WriteLine(device);
// This line produces error
IDevice dev = JsonConvert.DeserializeObject<IDevice>(device);
settingsDeviceName.Text = dev.Name;
}
Newtonsoft.Json.JsonSerializationException: Could not create an
instance of type Plugin.BLE.Abstractions.Contracts.IDevice. Type is an
interface or abstract class and cannot be instantiated. Path
'BluetoothDevice', line 1, position 19.
So I understand that IDevice is interface and my JSON string cant be deserialized nothing but into object. Any good ideas how to workaround it? Thanks!
This line JsonConvert.DeserializeObject<IDevice>(device); basically does this:
Read the JSON in device
Try to create the type of object you want to deserialize to, in this case, IDevice
Return you the new object with all the properties filled
The problem is with step 2. You can't create an instance of an interface. So you need to deserialize to a concrete object that implements IDevice.

What mechanism allows AS3 xml data to be referenced in a class yet persist when the original object is destroyed

I have a class instance called _refXMLManager that contains some XML data and I can reference the data by _refXMLManager.xmlData.
I have a second class called XMLREFTEST:
package {
public class XMLREFTEST {
private var _data:XML;
function XMLREFTEST(data:XML) {
_data=data
}
public function get data():XML {
return _data;
}
}
}
I can verify that the data in _xmlRefTest is indeed a reference by changing the value of a node in _refXMLManager and seeing it update in _xmlRefTest.
trace("_refXMLManager data: " + _refXMLManager.xmlData.test);
// _refXMLManager data: HELLO WORLD
_xmlRefTest = new XMLREFTEST(_refXMLManager.xmlData);
trace("_xmlRefTest data: " + _xmlRefTest.data.test);
// _xmlRefTest.data: HELLO WORLD
_refXMLManager.xmlData.test="Hi"
trace("_refXMLManager data: " + _refXMLManager.xmlData.test);
// _refXMLManager data: Hi
trace("_xmlRefTest data: " + _xmlRefTest.data.test);
// _xmlRefTest data: Hi
I then kill the 'master' object. (The kill function sets the original URLLoader and xmlData in _refXMLManager to null).
_refXMLManager.kill();
trace("_refXMLManager.xmlData==null: " + (_refXMLManager.xmlData==null));
// _refXMLManager.xmlData==null: true
trace("_xmlRefTest data: " + _xmlRefTest.data.test);
// _xmlreftest data: Hi
So my question is: what is happening in ActionScript that allows the original XML object to be disposed of and yet allows a reference to it to persist? I wondered if the reference just had to wait to be garbage-collected but that doesn't seem to be the case.
You misunderstand references and variables in AS3. You cannot kill an object if you still have a least one reference to it.
So _xmlRefTest.data still has a reference to the xml because it did prevent the object from being destroyed in the first place.
You did assume a few things that actually never happened:
The original object was never destroyed.
You never actually killed the original xml.
The xml cannot be GC because it never qualified for it in the first place since there's still at least one reference to it.

How to generate a csv file from field values of an apex page when clicking a command button in visualforce?

I'm working on a visualforce project that requires generating csv file from a group of field values.
I'm using the following code to generate csv, I'm supposed to click on a command button to generate the file but the problem is that when i click save on the apex page an empty file is generated without taking the required data.
Visualforce page:
<apex:page controller="test2" contentType="text/csv#{!fileName}.csv" showHeader="false" sidebar="false" standardStylesheets="false">
<apex:form >
<apex:outputText value="{!input}" escape="false"/>
<apex:commandButton action="{!exportContent}"/>
</apex:form>
</apex:page>
Controller:
public with sharing class test2 {
// Controller for ExportData.page,
// which expects to be handed the following POST variables:
// #inputdata(string) data to export (i.e. in CSV format)
// #filename(string) name of the file to export, e.g. 'AccountData'
public transient String input { public get; private set; }
public transient String fileName { public get; private set; }
public void exportContent(){
Map<String,String> params = ApexPages.currentPage().getParameters();
// We expect to be handed POST variables called 'inputdata' and 'filename'
fileName = params.get('filename');
if (fileName == null) fileName = 'Data';
input = params.get('inputdata');
if (input == null) input = 'No data provided.';
}
}
You will be extremely limited in how much data can be passed in the Query String using the PageReference.getParameters() method. Note that this method is limited to URL parameters. POST variables need to be handled by having a common controller class with a non-transient member to deserialize the data into. See PageReference.setRedirect(Boolean)
If set to false, the redirect is a server-side forward that preserves the view state if and only if the target page uses the same controller and contains the proper subset of extensions used by the source page.
I've put together an example of viewing a CSV via Visualforce - Prototype CSV viewer for Visualforce. You may be able to adapt it to your needs.
Incidentally, the Salesforce Stackexchange is a great place to ask Salesforce specific questions.

AS3: How to Deep Copy an Object

i have an object that i need to copy to my SharedObject data.
The problem is that the data property of shared object is read-only, so i can't clone my 'source' object and assign it to the shared object data, i have to make a copy of them in this way:
var so: SharedObject = SharedObject.getLocal("appData");
copyObject(sourceObj, so.data);
so.flush();
and the copy method:
public static function copyObject(sourceObject:Object, destinationObject:Object):void{
// this would be the code that i need
}
Also have in mind that my object has properties that are objects, so it has inside n leves of objects. That is why i can't simply make a for each and assign all properties on the first level, so what i need is to make a DEEP copy, probably recursive. I tried for hours to make this copyObject method with no success. Also i've searched on the internet but i didn't find any object copy that suits me.
Can someone please help me with this method? I would really apreciate it!
Thank you for your help!
The solution is to write your object to a byte array, encoded it to a string(optional - you can probably save the byte array as well, haven't looked it up) and save it to your shared object.
This function will take an object and turn it into a string
public static function serializeToString(value:Object):String{
if(value==null){
throw new Error("null isn't a legal serialization candidate");
}
var bytes:ByteArray = new ByteArray();
bytes.writeObject(value);
bytes.position = 0;
return Base64.encodeByteArray(bytes);
}
This one will get your object back from a string.
public static function readObjectFromStringBytes(value:String):Object{
var result:ByteArray = Base64.decodeToByteArray( value) as ByteArray;
result.position = 0;
return result.readObject();
}
The Base 64 encoding class you can find here https://github.com/juancgarcia/screenshotify/blob/master/Downloadify-652377f/src/com/dynamicflash/util/Base64.as.
You need to implement IExternalizable on all objects you want to store this way. The implementation includes making writeExternal method called against a ByteArray when you do writeObject(), and readExternal methods, that's called against a newly created instance, so your class should write the necessary metadata in order to make your object deep-cloned, including writing property objects.
Manual on IExternalizable
And on a side note, you should not store one object in the entire so.data, you'd better assign a field in so.data and stuff your object copy in there.
For complex objects I would use RegisterClassAlias:
import flash.net.registerClassAlias;
registerClassAlias("YourClassName", YourClassName);
var so:SharedObject = SharedObject.getLocal("objectName");
so.data.yourData = YourClassName.instance;
so.flush();
For simple Object type with deep level of simple data (primitives including arrays) I would simply use JSON.stringify() and JSON.parse() when reading back the data.

saving newtonsoft json response to isolatedstorage?

how can I save a list of Objects to isolatedstorage which is returned from a json call,
I already parse the result into a list of Objects, but I cannot seem to save it, I got a few xmlserialization issues, then I tried following this:
How to save a list of objects in isolated storage in wp7
but it led to a error
{System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: You must implement a default accessor on Newtonsoft.Json.Linq.JObject because it inherits from ICollection.
Opted to do the following:
private static void SerialiseAsJson(string textToSave, string fileName)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"..\..\NinjectModules\Fakes\FakeData\" + fileName))
{
file.WriteLine(textToSave);
}
}
Usage:
SerialiseAsJson(JsonConvert.SerializeObject([object to serialize]),"filename.JSon");