How do you detect the AIR API version?


#1

Very often overlooked in the Authoring Guidelines in the release notes

for Flash/AIR 29 for example

Add “-swf-version=40” to the ‘Additional compiler arguments’ field

using the app XML is not enough

<application xmlns="http://ns.adobe.com/air/application/29.0">

you specifically have to tell the compiler to publish a particular SWF version
eg. -swf-version=40

and to verify at runtiem this SWF version, or what AIR API version is supported by your app

in ActionScript you would use something


private function onComplete( event:Event ):void
{
    trace( "loaderinfo swf version = " + loaderInfo.swfVersion );
}

public function main():void
{
    loaderInfo.addEventListener( Event.COMPLETE, onComplete );
}

Yep, you have to wait for the event otherwise you’ll get the error

Error: Error #2099: The loading object is not sufficiently loaded to provide this information.

an alternative way is to parse the SWF itself
see this gist Detect AIR SWF version

in short 2 methods

        private function _getAIRSWF():String
        {
            var na:NativeApplication = NativeApplication.nativeApplication;
            var swf_file:String      = "";
            
            if( na )
            {
                var descriptor:XML = na.applicationDescriptor;
                var ns:Namespace   = descriptor.namespace();
                
                swf_file = descriptor.ns::initialWindow.ns::content;
            }
            
            return swf_file;
        }

and

        private function _parseSWFVersion():uint
        {
            var air_swf:String = _getAIRSWF();
            var air_file:File = File.applicationDirectory;
                air_file = air_file.resolvePath( air_swf );
            
            if( air_file.exists )
            {
                var fs:FileStream = new FileStream();
                    fs.endian = Endian.LITTLE_ENDIAN;
                    fs.open( air_file, FileMode.READ );
                    trace( "endian = " + fs.endian );
                    trace( "bytesAvailable = " + fs.bytesAvailable );
                    trace( "position = " + fs.position );
                    
                // SWF magic number
                var magic:Array = [ fs.readUnsignedByte(), fs.readUnsignedByte(), fs.readUnsignedByte() ];
                    magic.reverse();
                    magic.forEach( function(el:*, i:int, a:Array):void { a[i] = String.fromCharCode(el); } );
                
                var signature:String = magic.join("");
                if( (signature == "SWC") || (signature == "SWF") )
                {
                    // valid signature found
                    
                    var version:uint = fs.readUnsignedByte();
                    fs.close();
                    return version;
                }
                else
                {
                    trace( "This is not a valid SWF file (signature=" + signature + ")" );
                    fs.close();
                    return 0;
                }
            }
            
            return 0;
        }

So why would you parse the SWF itself and why not simply use the API loaderInfo.swfVersion ?

you may not want to wait (because you know it is AIR and the SWF is already there on the filesystem) or maybe you want to find out the SWF version of an external SWF before loading it etc.

but mainly you do not want to wait for an event :stuck_out_tongue: