Externalize app version info - actionscript-3

I want my app's preloader to display version/build info that I have in an XML file. Obviously, the preloader can't pick it up because it waits for XML file to load. Is there another approach that I can use to externalize my version/build info and ensure it's in my app early?
Any tips are helpful and very appreciated.
Thanks!

I typically use compiler constants for this data, as it's available at build time, and can be easily baked into the app.
-define+=CONFIG::VERSION "1.0.1-a"
private static const version:String = CONFIG::VERSION;
<s:Label text="{version}" />

Related

MvvmCross - structuring shared View Models and Views

Love this framework thus far.
That said, hit my first roadblock. I have created an MvvmCross-based library (actually a few libraries) that performs login services that will be used across multiple cross-platform applications of the same family. What I can't quite figure out is how to plug these login libraries into my other applications (which will also be using MvvmCross). I want to be able to re-use the same ViewModels and Views across these apps.
Assume that I've read and watched a lot of slodge's videos. :) Which are very good.
I think MvvmCross with two core libraries was about the closest thing to what I'm trying to do, which is just smash MvvmCross projects together and make it all magically work. But going by that post, which had some inconsistencies in the code samples, I've been unable to get this working.
There are 2 methods in Setup which tell mvvmcross where to look for Views and ViewModels. If you override these then the system should find your views and view models.
protected virtual Assembly[] GetViewAssemblies()
{
var assembly = GetType().Assembly;
return new[] {assembly};
}
protected virtual Assembly[] GetViewModelAssemblies()
{
var app = Mvx.Resolve<IMvxApplication>();
var assembly = app.GetType().Assembly;
return new[] {assembly};
}
Beyond this, the only additions to this that I'm aware of are that you might need:
to give wp some extra help in finding the xaml urls for any views which are in additional assemblies - by default mvx only looks for the xaml uri in /views, not in any other folder in any other assembly. One way to provide the xaml urls is to add a MvxPhoneViewAttribute within the View's c# file, another is to override the MvxPhoneViewsContainer to make it provide custom urls.
to adjust some of the android project settings in order to get resources shared from libraries to main project (although this functionality has gotten much better within xamarin.android this year.

Html applet tag, accessing through chrome developer tools

i happen to receive a Html with an applet tag, is there a way to access the class received through chrome developer tools, i cant see it in the scripts. If there isnt how can i access it?
<applet name="tradesapp" id="tradesapp" code="loader3.SunLoaderApplet.class" archive="loader_20110113.jar" codebase="http://ih.advfn.com/" width="1100" height="2000" mayscript="" alt="This browser either has java disabled or does not support it" title="Java"><param name="manifestcrc" value="1211857157"><param name="storagepath" value="ih.advfn.com"><param name="masterloader" value="master"><param name="initial_focus" value="false"><param name="cache_archive" value="loader_20110113.jar"><param name="cache_version" value="1.0.7.7"><param name="java_arguments" value="-Dsun.java2d.d3d=false"><param name="advfn_url" value="http://ih.advfn.com/"><param name="streamer" value="stream-9.advfn.com"><param name="user" value="ih_340884"><param name="root" value="advfnclient.framework.BaseControl"><param name="page" value="advfnclient.TradesContainer"><param name="tz" value="US/Eastern"><param name="clearAllDateStamp" value="1272534624504"><param name="clearCacheDateStamp" value="1272534624504"><param name="language" value="us"><param name="view" value="ih"><param name="config_name" value="trades"><param name="config_default" value="Default"><param name="params" value="w=1100&h=2000&symbol=N%5EMSFT&montage=true&sources=afx:ukreg:rssnon&dims=664 79 15 0&col_widths=45 55 344 90 115&sid=1f58fa6b4ea88725c5b8e23d614a6e80&page_key=1338581393&w=1100&h=2000&pid=applet_embed&mypid=trades"><center><iframe width="600" height="300" src="/p.php?pid=javadisabled"></iframe></center></applet>
Chrome doesn't include a Java debugger and an applet isn't a script.
You can access it via document.getElementById('tradesapp'); in the JS console. If you want to do anything with it, then the applet will have to explicitly expose methods to JavaScript.
I suspect this is not your Java project, so I can't imagine Quentin's advice will help you. It sounds to me like you want to run the Java Applet yourself, perhaps making changes and having access to a debugger. I decided to see what I could do as I've never had experience with this kind of stuff before.
First of all, you can download the .jar file in the archive property. In your case it looks to be located at http://ih.advfn.com/loader_20110113.jar
You can then use Java Decomipler to decompile the .jar file. If you do so, you'll see that this jar file acts as a loader, and pulls more java classes from advfn.com. It saves them in the location given by:
String path = System.getProperty("user.home");
On windows this is C:\<USER>\advfn
You can decompile these classes as well if you're interested. You'll be left with an approximation of the original source code. In this case, a fairly good one.
If want you go one step further and decide to build the project yourself, you can import the classes into Eclipse. You'll notice there are some strange errors such as the following:
LoadFile(String paramLong, long arg3)
{
this.name = paramLong;
Object localObject;
this.size = localObject;
}
I've never built a decompiler myself and am not at all familiar with Java bytecode, but if I had to guess, I'd imagine that the decompiler was trying to represent a local instance of the argument that was passed in to it.
The fix is fairly obvious once you know this.size is of type Long.
LoadFile(String paramLong, long arg3)
{
this.name = paramLong;
this.size = arg3;
}
If you continue to make these changes, your code will compile successfully. But it still won't run as you're missing parameters set in the HTML. A sample line in LoaderApplet.java is as follows:
this.manifestCRC = Long.parseLong(getParameter("manifestcrc"));
If you return to the HTML page you found this at, you'll find a variety of parameters are specified there. You should be able to go through your project and replace requests for parameters with their appropriate values.
This was my first experience decompiling Java, so I might have missed a few details. Let me know if you need more help.

AS3: Handle BulkLoader.COMPLETE event on AS3 Preloader

I am trying to use BulkLoader (https://github.com/arthur-debert/BulkLoader) to preload all assets of my AS3/Flex application. Right now it is working and I am able to access the contents everywhere on my Main module (where my BulkLoader instance lives).
My problem: I need to handle the BulkLoader.COMPLETE event from my preloader (pre.as living next to Main.mxml on src/), to allow the user to exit the preloader and enter the application ONLY after BulkLoader.COMPLETE was fired.
Thanks!
Why not pass the reference to the BulkLoader instance?
Somethinglike this:
preloader.setLoader(_bulkLoaderInstance or name)
or
var preloader:Preloader = new Preloder(_bulkLoaderInstance or name)
BTW, the LoaderMax from Greensock is better (fewer bugs, more reliable events, nicer API).

Bug? LoaderInfo getLoaderInfoByDefinition security sandbox violation in AIR

This question is specific to Adobe AIR ActionScript/Flash applications. I've spend quite some time researching this and kept finding discussions about either the Flash Player security model when running in the browser, where issues with SWF loading can be mitigated in various ways (loading from the same domain, using a crossdomain.xml file, etc.) or for AIR HTML applications, where the JavaScript security model is discussed with it's per-frame sandboxes and the sandbox bridge approach. My problem is different, I believe.
First some code. To demonstrate, I created a very simple Flex application (LoaderInfoTest.mxml):
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onCreationComplete(event)">
<mx:Script>
<![CDATA[
import flash.display.LoaderInfo;
import flash.system.ApplicationDomain;
import flash.utils.getQualifiedClassName;
import mx.events.FlexEvent;
public function onCreationComplete(event:FlexEvent):void
{
// the following line of code throws an exception
var info:LoaderInfo = LoaderInfo.getLoaderInfoByDefinition(this);
}
]]>
</mx:Script>
</mx:WindowedApplication>
... and an application.xml descriptor file (LoaderInfoTest-app.xml):
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<application xmlns="http://ns.adobe.com/air/application/1.5.2">
<id>LoaderInfoTest</id>
<filename>LoaderInfoTest</filename>
<name>LoaderInfoTest</name>
<version>v1</version>
<initialWindow>
<content>LoaderInfoTest.swf</content>
</initialWindow>
</application>
I build this using Flash Builder 4 Beta, but I presume the issue remains the same when using the SDK command line tools. When executing this either from within Flash Builder or from the command line via:
> adl LoaderInfoTest-app.xml .
I get a popup with this exception:
Security sandbox violation: caller app:/LoaderInfoTest.swf cannot access LoaderInfo.applicationDomain owned by app:/LoaderInfoTest.swf. at flash.display::LoaderInfo$/getLoaderInfoByDefinition() ...
I don't understand why the SWF cannot access the LoaderInfo.applicationDomain property (presumably a protected or internal property) owned by itself. The documentation for LoaderInfo.getLoaderInfoByDefinition states that it's possible for a SecurityError to be thrown, if "[t]he caller is not running in the local trusted sandbox". Unless I really have a gross misunderstanding of the AIR security model, a local SWF runs with full trust (application sandbox). So, why is this not working? Is it a bug in the AIR runtime?.
I should note that in a different scenario, when running this code as a pure Flash (not AIR) application in the Flash player, it does work.
The best answer would be some sort of configuration or setting I can change to make this work (maybe in the application descriptor?) ... or pointing out where I am making a mistake. The second-best answer would be a definite source of explanation of why this will never work.
1st Edit - Before anyone points it out: I know that inside the onCreationComplete method, this.loaderInfo gives me access to the current LoaderInfo instance. My example here is the simplest I could come up with to demonstrate the "problem." The context in which I want to use LoaderInfo.getLoaderInfoByDefinition(this) is not a DisplayObject instance.
2nd Edit - I am considering even accepting a link to where I can post a bug to Adobe AIR's issue tracker as an answer. The public Flex issue tracker doesn't count, because this is not a Flex problem.
3rd Edit - It is apparent that there are differences between the "local trusted sandbox" and the "AIR application sandbox," but (some of) these differences seem non-sensical and I now consider them a bug, at least in the context of this question and especially because it works in Flash Player.
The documentation is correct that getLoaderInfoByDefinition is available only to content in the localTrusted sandbox. Although AIR application content has many privileges, it is not in localTrusted and therefore cannot use the API.
It's certainly a reasonable request, however, to add access for application content.
As a workaround, you can use this API (and Sampler APIs) in AIR by loading another SWF in localTrusted sandbox. To do this, you need to add the file to one of the trusted lists, and load the file with a file:// URL (not app:/). There are then a number of ways for the localTrusted and application content to communicated.
You can file bugs against AIR (as well as make feature requests) at www.adobe.com/go/wish
I suspect the security error may be a red herring. It doesn't look like there should be one here.
This issue is also showing up in a regular flash application. Basically, I have a helper class called UrlInfo.
It's constructor looks like this
import flash.display.LoaderInfo;
public class UrlInfo
{
private var _loaderInfo:LoaderInfo;
public function UrlInfo():void
{
_loaderInfo = LoaderInfo.getLoaderInfoByDefinition(this);
}
}
In a fla file, I have this:
import my.namespace.UrlInfo;
var ui:UrlInfo = new UrlInfo();
I get the same error:
SecurityError: Error #2119: Security sandbox violation: caller file **SAMEFILE.swf** cannot access LoaderInfo.applicationDomain owned by **SAMEFILE.swf**.
at flash.display::LoaderInfo$/getLoaderInfoByDefinition()
at com.honda.ttd.content.as3.util::UrlInfo()
at urlinfo_fla::MainTimeline/frame1()
Launching the .html that calls the swf does not trigger this.
Launching the .swf does trigger this.
I know that I can fix it by going to the flash settings and adding the location of the swf into the Flash Security Settings Tab.
For instance, if the SAMEFILE.swf is on my Desktop, I can add C:/ to the list of trusted locations.
I AGREE THAT THIS IS ODD because the file is accessing itself, yet it is violating some security. I would like to know if there is any fix for this or if this is actually expected behavior.

Logging API for AS3

quick question, I've been looking for a simple logging tool for AS3 projects (I do not want any Flex dependencies) and my impression so far has been that there is no actively developed project.
What I need is basic logging, and adapters to allow me to send logging to file (using AIR and a LocalConnection maybe) and maybe send to html div etc.
Anyone have any opinions on a simple, light weight project?
We have recently started a project called AS3Commons that contains an early implementation of an AS3 Logging framework. We're aiming to provide a Logging abstraction API that allows you to plug in adapters for other logging frameworks. We also have a built-in logger that logs using trace.
It's usage is similar to other logging frameworks.
private static var logger:ILogger = LoggerFactory.getLogger("com.domain.Class");
Check it at http://code.google.com/p/as3-commons/
Any feedback is appreciated.
This is the best as3 logger by far!!!!
http://arthropod.stopp.se/
There is a standard Logging API in AS3. You can set it up to log to different targets. For instance, if you're using AIR, you could get it to log to a file using the FileTarget in as3corelib.
Setting up:
var logFile:File = File.applicationStorageDirectory.resolvePath("logs/logfile.log");
var logTarget:FileTarget = new FileTarget(logFile);
logTarget.filters = ["path.to.Class"];
logTarget.level = LogEventLevel.ALL;
logTarget.includeDate = true;
logTarget.includeTime = true;
logTarget.includeCategory = true;
logTarget.includeLevel = true;
Log.addTarget(logTarget);
Logging:
var log:ILogger = Log.getLogger("path.to.Class");
log.info("testing the logging...");
I'm always surprised at the number of people who haven't heard of Arthropod. It does everything you described and more. Including password encrypted connections. Arthropod is also set up in a way that it is very easy to make quick edits to the class for your specific needs.
I've got a Flash-friendly logging project going. It's nothing big (yet?) but it's light and handy. It does (optionally) take advantage of Arthropod (a great project) but you can pretty easily shoot the output anywhere you like. It works similarly to the Flex framework so if you are familiar with that then the transition would be painless.
You can read about the project and download the goods here.
MonsterDebugger has more options than it sounds like you're looking for. But it is small and has some very handy features. Including instance inspection, editing properties, calling methods remotely from the air console, and browsing/editing the display tree.
http://monsterdebugger.com/
They made a game so you could learn the debugger, its great.
I found the best solution for me is combining as3commons-logging with Arthropod, like so:
LOGGER_FACTORY.setup = new SimpleTargetSetup(mergeTargets(new TraceTarget(), new ArthropodTarget()));
Then, if you have a client who is having issues but can't tail the flashlog, they can just fire up Arhtropod. Awesome!