May 22, 2012

StageAspectRatio Enhancements in AIR 3.3

One must have come across many mobile applications(mostly games) that remain in landscape orientation across their lifetime. They start in landscape orientations and remain in landscape orientations irrespective of the orientation in which the device is held or moved. A landscape only application should ideally support both landscape orientations namely Landscape_Left and Landscape_Right and should not auto rotate to any portrait orientation if the device is held in one of the portrait orientations.

Prior to AIR 3.3, StageAspectRatio supported two public constants PORTRAIT and LANDSCAPE. Using one of these values in the aspectRatio tag in the application descriptor would only lead to the application opening up in PORTRAIT or LANDSCAPE orientation respectively. However, the Stage would re-orient in all orientations as per the new device orientation. For example:- with StageAspectRatio set to PORTRAIT, an app would open in PORTRAIT orientation but would reorient to LANDSCAPE_LEFT orientation when device orientation was changed to LANDSCAPE_LEFT.

In order to develop a LANDSCAPE(or PORTRAIT) only mobile application, one was expected to cancel the automatic reorientation by adding a listener to orientationChanging event in the Stage Object by calling preventDefault() method when afterOrientation values were PORTRAIT (or LANDSCAPE).

From AIR.3.3 onwards, developing LANDSCAPE (or PORTRAIT) only applications has been made easier. With the aspectRatio set to  LANDSCAPE(or PORTRAIT) and autoOrients set to true the application descriptor,the stage would automatically reorient only in LANDSCAPE (or PORTRAIT) orientations. Handling orientationChanging events and calling preventDefault() is no longer required to achieve this behavior. One can also change the StageAspectRatio at the runtime by calling  the Stage.setAspectRatio() with the desired aspect ratio.

 

New AspectRatio Constant: “ANY”

A new StageAspectRatio constant “ANY” is introduced in AIR 3.3 to assist you in creating applications that should automatically reorient as per the device orientation. Setting the aspectRatio tag in application descriptor to “ANY” would lead to application launching as per the orientation in which the device is held. Such an application would reorient as per the device orientation.

To summarize, Stage orientation is always in sync with the StageAspectRatio set in application descriptor or programmatically in ActionScript unless set otherwise using Stage.setOrientation(). Following table summarizes the supported Stage orienatations as per the device orientation.

StageAspectRatio         Supported Stage Orientations
 ANY PORTRAIT, UPSIDE_DOWN, LANSCAPE_LEFT & LANDSCAPE_RIGHT   
 PORTRAIT PORTRAIT & UPSIDE_DOWN
 LANDSCAPE LANSCAPE_LEFT & LANDSCAPE_RIGHT

Please Note:-

  1. AIR 3.3 is currently available only in pre-release. 
  2. Stage.autoOrients needs to be set to true in application descriptor or programmatically using autoOrients property in the Stage class to reorient the Stage automatically as per the device orientation.
2:33 PM Comments (0) Permalink
May 19, 2012

Protected: Common issues faced in developing Native Extensions for AIR on iOS

This post is password protected. To view it please enter your password below:


2:25 PM Comments (0) Permalink
May 18, 2012

Using platformsdk for iOS on Windows

With AIR 3.3, it is possible to use platformsdk switch for iOS on a Windows machine too. For using this feature, one needs to copy the desired iOS SDK (iPhoneOS.x.y.sdk) on their Windows machine and use the platformsdk switch of the ADT:

adt -package -target (ipa-test|ipa-test-interpreter|ipa-debug|ipa-debug-interpreter|ipa-ad-hoc|ipa-app-store) SIGNING_OPTIONS -provisioning-profile <path to .mobileprovision><output IPA file> <application.xml> <SWF> <assets> -extdir <path to extensions folder> -platformsdk <path to the iOS SDK folder>

Now, this seems fairly simple, the only difficulty which may arise is while copying the SDK from Mac to Windows machine(as symbolic links are present on Mac, which need to be copied as actual files on Windows, else packaging would fail).

The following ways of copying the SDK are recommended to preserve the symlinks:

1) Compress the iOS SDK using “zip -r” on the terminal and copy it using  “cp -R”. Extract on the Windows machine.

2) Copy the dmg on a Windows machine and extract it to get the iOS SDK.

Currently, platformsdk can’t be used for iOS in Flash Builder on Windows. Support will be available soon.

5:20 PM Comments (0) Permalink

Stage3D FAQs

In this blog entry I will gradually pen any interesting observations that I come across with stage3D which will help actionscript developers gauge a better insight as to what happens behind the scenes.

For the folks who are unaware of stage3d, Stage3D is a new model of rendering developed by Adobe which provides a set of low level GPU accelerated APIs advanced 2D and 3D capabilities across multiple screens and devices (desktop, mobile, and TV) through the runtimes. These APIs provide advanced 2D and 3D developers with the flexibility to leverage GPU hardware acceleration. Please visit http://www.adobe.com/devnet/flashplayer/stage3d.html for more details.

1) Calls synchronous or asynchronous

One question that would perplex stage3d code writers would be as to how do calls stack up. This may assist them in understanding why certain calls take longer than other. Almost all calls in Stage3D are asynchronous. Anything in stage3d is passed as a request to the gpu which gpu then takes up on its leisure and processes them as it feels like. Following are the exceptions and are calls that are synchronous in nature

i) present() or clear(): If gpu is not done with the previous batch of calls then either of these calls will wait synchronously for the gpu to finish what it was doing previously

ii) Uploads done to gpu memory behave synchronously. CPU is a participant in the transfer and hence this call behaves synchronously. Minimizing uploads is a key thing in a memory constrained mobile environment. Avoid having a situation where you are uploading, drawing, uploading again and again. Upload everything to the gpu once at the beginning of the application and then draw.

iii) DrawtoBitmapData is again one call that requires a conversation between the cpu and gpu. This call again is synchronous.

As a general rule of thumb do not try to time gpu calls as the amount of data being drawn and time to draw that data is something that does not vary linearly. Some calls are blocking and the time that it takes for you to get the control back could actually be because of a host of earlier calls.

2) Multiple draw calls vs one draw call

Another simple query would be if one should draw everything in one drawTriangles call or use multiple drawTriangles call to draw the same content and the answer is what you would expect. Use one draw with large amount of content. GPUs love parallelism and providing more data allows them to work on a lot of data asynchronously.

3:44 PM Comments (0) Permalink

Performance Optimizations

Within this blog entry I will enlist some of the simple optimizations that one can do within actionscript 3 and particularly iOS mobile applications

1) No modifications to display list within timer events

In case you have a timer event firing at a very high rate and your application is making changes to the display list within this event handler. Consider that the fps of your application is lesser than the rate at which your timer is firing. In such a case you will be making changes to the display list which will never be actually used and you will be making unnecessary calculations within these timer events slowing down the player.

Instead the recommendation in such a case is to use stage.invalidate() call and use the RENDER event. In case you have a very deep display list, do not commit changes directly to the display list instead hold the changes in temporary variable and once you feel that sufficient changes have been made to the display list, then call stage.invalidate(). This will cause a RENDER event to get fired. One should use this event to make changes to the display list from the temporary variables which were holding these changes.

2) Keep constructors small

Constructor code is not JIT and is interpreted because of which it runs slow. Avoid having large constructors. In case of iOS however constructors are AOT (Ahead of time) compiled so this issue makes no difference for iOS.

3) Image handling

As a general rule of thumb, avoid embedding images and load them only on runtime when needed. Loading images at runtime results in a little more complicated code but if start up time is the requirement then definitely go for loading images at runtime rather then embedding them as part of swf.

4) Image formats

This is a general guidance and not related to actionscript 3. In case you are using a small image (lets say something around 10 x 10 image) then one should a png image. If the image is that of a face or something that has a lot of textures then definitely use jpg images. Obviously, if you need transparency in your images then you have no choice but to use png images.

5) Image sizes

It is important to use right sized images when making mobile applications. Working with large image sizes can be catastrophic to fps. If your rendermode is gpu and if you are using a mac then make sure that you check gpu utilization. This is provided by the open gl es driver tool in instruments. If the shader utilizations are coming in at 100%, then take it is as a hint to reduce image sizes.

Do visit http://help.adobe.com/en_US/as3/mobile/flashplatform_optimizing_content.pdf for similar optimizations you can do for your applications

3:43 PM Comments (2) Permalink
May 6, 2012

Using new Simulator Support feature for iOS

With Adobe AIR 3.3, support for native iOS simulator would be available for application development.

Prior to this feature, the only way to test AIR  applications on iOS was to have an actual device along with a developer certificate from Apple. With simulator support now available however, there is no need to obtain a developer certificate (which is a time consuming process) or to create a provisioning profile before starting to develop an AIR application. A p12 certificate, which can be created by the developer himself would be sufficient.

Native simulator for iOS is very helpful in testing and debugging AIR applications. Because support for this enhancement is currently not available in Flash tooling,  one could use the following adt commands below to use this feature .

Simulator for iOS is based on x86 architecture and therefore two new targets have been added in ADT to support the same.

Targets are:

1.) ipa-test-interpreter-simulator
2.) ipa-debug-interpreter-simulator.

To package application for simulator in any of  the above targets, execute either of the following commands:

Test Interpreter Target

adt -package -target ipa-test-interpreter-simulator -storetype pkcs12 -keystore Certificates.p12 -storepass password Sample_ipa_name sample_ipa-app.xml sample_ipa.swf

Debug Interpreter Target

adt -package -target ipa-debug-interpreter-simulator -connect -storetype pkcs12 -keystore Certificates.p12 -storepass password Sample_ipa_name sample_ipa-app.xml sample_ipa.swf

If you observe carefully, you will find that for debug target I have not specified any IP address . This is so because  simulator will always be launched on the local machine and therefore there is no need to specify an IP address.

Now if you have packaged your application, it is time to  install it by executing the command given below:

To install application in simulator

adt -installApp -platform ios -platformsdk (path to sdk eg /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk) -device ios-simulator -package sample_ipa_name.ipa

NOTE: This feature doesn’t work well with Xcode 4.3.2 . The problem arises because the latest version of Xcode is installed as a .app and this feature requires mobile framework to be there in /developer directory. As a workaround you would need to install an older version of Xcode too or wait for the release version of AIR.

After installing the application, try to launch and run it on Simulator using the command given below:

To launch application in simulator

adt -launchApp -platform ios -platformsdk (path to sdk eg /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk) -device ios-simulator -appid Sample_ipa_name

The application can be uninstalled from the simulator directly through UI or if you want to uninstall it using command line then use the command below.

To uninstall application in simulator

adt -uninstallApp -platform ios -platformsdk (path to sdk eg /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk) -device ios-simulator -appid Sample_ipa_name

NOTE: if you uninstalled the application using ADT command then application will get purged but its icon still keeps on showing on simulator . It will goes away once you restart the simulator.

Native Extensions and Simulator

I have already mentioned above that simulator on iOS is based on x86 architecture. To support  native extension on simulator, a new platform name (iPhone-x86) has been added in extension.xml.  All the commands to mention ane are similar to that with device, so I am not mentioning the commands for packaging. However,  please note that for packaging native extension library.a file required from XCode should be compiled for  simulator target . A typical extension.xml for simulator ane would look like below:

<extension xmlns=”http://ns.adobe.com/air/extension/3.1“>
<id>com.cnative.extensions</id>
<versionNumber>1</versionNumber>
<platforms>
<platform name=”iPhone-x86″>
<applicationDeployment>
<nativeLibrary>library.a</nativeLibrary>
<initializer>TestNativeExtensionsInitializer</initializer>
<finalizer>TestNativeExtensionsFinalizer</finalizer>
</applicationDeployment>
</platform>
</platforms>
</extension>

3:46 PM Comments (5) Permalink
April 26, 2012

iPad3 – Retina display using Adobe AIR

In an Adobe AIR application, if one wants to use Retina display on iPhone or iPod , this can be achieved using following tag under <iPhone> tag in application descriptor.

<requestedDisplayResolution>high</requestedDisplayResolution>

But this doesn’t work with recently launched iPad3 devices, so here is the workaround.

If you have AIR 3.1 or greater and a Mac machine, download and install new XCode with iOS 5.1 or greater SDK.

Now make use of “platformsdk” switch of ADT, following is the command line example.

adt -package -target ipa-app-store -provisioning-profile <path to provisioning file> -storetype pkcs12 -keystore <path to keystore file> -storepass <password> HelloWorld.ipa HelloWorld-app.xml HelloWorld.swf -platformsdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/

Note – Please make sure that HelloWorld-app.xml has the tag requestedDisplayResolution set to “high”.

The resulting ipa will be displayed with doubled resolution on an iPad3 device (1536×2048).

Capabilities.screenResolutionX : 1536
Capabilities.screenResolutionY : 2048

 

10:23 AM Comments (3) Permalink
March 5, 2012

AIR App Compliance with Apple Data Storage Guidelines

AIR applications targeted for iOS may get rejected in the application review process with the reason “Rejection: 2.23 Apps must follow the iOS Data Storage Guidelines or they will be rejected“. Usage of File.applicationStorageDirectory or Local Shared Objects (LSOs) in the application might be the reason. Recently, Apple has updated the Data Storage Guidelines with the release of iOS 5. Since the guidelines are accessible only to registered iOS developers, let me summarize the key points below:-

  • The entire home directory is backed up to iCloud by default, except the Application bundle itself, Caches directory and the tmp directory.
  • In order to minimize the data that needs to be backed up, Apple expects the developer to adhere to the following guidelines:
    • Only user generated data, which other wise cannot be recreated like an image capture or voice recording should be stored in Documents directory.
    • Application Support Directory must be used to store only application specific data files. For example:- application configuration files or game levels. Data stored here is not vulnerable to be purged under low memory conditions.
    • Data that can be regenerated such as downloadable content should be stored only in Caches directory. Caches directory must be used to store application specific files that can be re-created easily. iOS may take the liberty to delete this directory occasionally when the device is low on memory space. Hence, critical application data must never be stored here, since it faces a risk to be purged under low memory conditions.
    • Temporary data should be stored in tmp directory. All application specific files that need not persist between application launches must be put here and should be deleted at application exit. 

AIR developers, too, must adhere to these guidelines while developing apps targeted for iOS platform and align the files created by their application accordingly. AIR maps File.applicationStorageDirectory and Local Shared Objects (LSOs) inside “Application Support Directory” . Since this directory is backed up on iCloud by default, one must use it only to store application data files that must not be deleted under low memory conditions. LSOs must also be used on iOS to store critical application specific data only, such as current game state.

Since there is no direct property to access the Caches and tmp directory in AIR, let me discuss a workaround if one faces a need to use these directories. Instead of using the static directory paths populated by File class properties, one can create global File objects that point to the corresponding directories and finally write to any file inside those directories. Sample code snippet can be found below.

public var cacheDir:File = null;
public var tempDir:File = null;

//Initialize the Objects with proper paths.
var str:String = File.applicationDirectory.nativePath;
cacheDir= new File(str +"/\.\./Library/Caches");
tempDir = new File(str +"/\.\./tmp");
var fr:FileStream = new FileStream();
fr.open(cacheDir.resolvePath("myCache.txt"),FileMode.WRITE); fr.writeUTFBytes("works");
fr.close();

More details on how to make app backups more efficient on iOS platform can be found here.

5:21 PM Comments (0) Permalink
October 21, 2011

Using release swf for publishing AIR applications

Adobe tools like Flash Builder allow you to compile actionscript sources of your application and then package all the swf content and assets as .air, .ipa, .apk and native package formats.

This post is meant to stress on the importance of using Release version of swf file for packaging when you intend to publish it on an application store.

Why should I care to create the release version of a swf?

There are two major advantages of using the release version for publishing applications:

  • Application Size – The debug version of a swf contains lot of extra information which is required for debugging during development. As a result, the size of debug version of a swf is always more than the corresponding release version.
  • Memory Size – Because of extra information, an application with debug swf consumes way more memory than its corresponding release version. For a sample Flex app, the memory usage can go down from 22 MB to 14 MB if one switches to using release version of swf.
  • Application Performance – Some of the extra code embedded in a debug swf is actually executed during runtime, and so you might see performance gains with the release version of the swf.

If you are packaging your application for iOS, you would see some more improvements:

  • Application Packaging Time – If you are using ‘Standard Packaging’ mode (which generates native ARM code for your swf content), the packaging time depends on the amount of byte code available in the swf file. As a result, you would most likely see a significant drop in packaging time if you use release version of a swf.

With release version of swf, the reduction in application size is also much more prominent while packaging application for iOS.

How can I create the release version of a swf?

There are two ways to do this:

  • Use ‘Export Release Build’

This is the recommended way. In Flash Builder, select Project->Export Release Build, provide all the required information to package the application. This mechanism doesn’t actually put the release swf in some folder like ‘bin-release’, though it is actually packaged into the application package (.apk, .ipa etc.) file.

  • Use Compiler option (-debug=false)

In Flash Builder, add “-debug=false” in Project->Properties->Flex Compiler->Additional compiler arguments, and build the application. With this compiler option provided, swf created with any configuration would always be the release version. Clicking on ‘Run” or “Debug” would however create this release swf in the “bin-debug” folder. You can use this compiler option (i.e -debug=false) even if you are using mxmlc compiler on command line.

3:49 PM Comments (0) Permalink
August 16, 2011

Versioning in Flash Runtime (-swf-version)

AIR 3 Beta got released on Adobe Labs last week, providing a great opportunity to try out some of the exciting new enhancements that have been made by the team. Christian’s post provides the quick steps to get started with the AIR 3 Beta SDK.

In the “Additional compiler arguments” box, you need to add “-swf-version=13″ to make use of the new APIs introduced in AIR 3. So one question you might have is that if you are already specifying the namespace in your AIR application descriptor as 3.0, then what is the need of specifying more versioning information? Let me share with you some background about versioning in Flash Runtime.

SWF Versioning

Starting with AIR 2.6 release (and Flash Player 10.2), we changed our SWF versioning approach. Earlier we used to increase the SWF version only with major release of Flash Player. For eg.

Flash Player Version
Adobe AIR Version
SWF Version
9.0.15.0 - 9
9.0.115.0 - 9
10.0 1.5 10
10.1 2.0 10
10.2 2.6 11
10.3 2.7 12
- 3.0 (Beta) 13

Post AIR 2.5 (Flash Player 10.1) however, we started increasing the SWF version with every release, both minor and major. So we docoupled the SWF version with versioning Flash Player or Adobe AIR.

API Availability

A new version of Flash Player and AIR might introduce certain new APIs that were not available in the previous versions. If an application makes use of those new APIs, then the currently installed Flash Runtime (on the end user’s desktop/mobile platform) would check if it is capable enough to execute those new APIs. So let’s see how exactly that happens in the Runtime.

Flash Player – When Flash Player identifies content that is newer than itself (defined by the SWF version) it attempts to run the content as best it can, but eventually fails if the content tries to use features that don’t exist in that version of the player.

Adobe AIR – Unlike Flash Player, AIR does not attempt to run content that was built for newer versions of AIR. The correct API set to be exposed to the application depends on the lower of the following two:

1. SWF version corresponding to the namespace in the application descriptor
2. SWF version of the root SWF in the application

Coming back from where we started – To ensure that newly introduced APIs are available to you while using AIR 3 Beta SDK, remember to add “-swf-version=13″ to the compiler arguments.

3:29 PM Comments (1) Permalink