Posts in Category "Uncategorized"

Launch Images on iOS with Adobe AIR

Introduction:

To make an impression of a super-quick response and to give the application suitable time to load completely, iOS introduced the concept of a launch image. A launch image is the first interaction of an application with the user; so it becomes vital to have a properly displayed image at start up. The launch image is displayed while the application is loading, and as per iOS human interface guidelines, it’s one of the must-have requirements for an application.

For Adobe AIR applications, a launch image must remain visible until the AIR runtime is completely initialized. To accomplish this, AIR runtime displays the same launch image as displayed by iOS until the application is ready for use.

To support an application on all iOS devices, one should include launch images of various sizes and resolutions as per the following naming scheme.

Naming scheme

Basename + screen size modifier + orientation + scale + device + .png

Basename is the name specified in UILaunchImageFile key in the InfoAdditions element in the application descriptor. Usually it is given as the value, Default.

Screen size modifier when multiplied by the scale factor of the device, gives the actual dimensions of the device.  For example, screen modifier for iPhone 5s is 568h, which, when multiplied by scale factor of 2 gives 1136h – the actual height of iPhone 5s in pixels.

Orientation– different launch images can be displayed on an iPad and iPhone 6 plus, based on their orientation, at the time of application launch.

Scale factor for non-retina display devices is 1x and for retina devices it is 2x. The recently launched iPhone 6 plus has a scale factor of 3x.

Device portion is provided in applications that can run on both iPhone and iPad. Its value can either be ~iphone or ~ipad.

With the introduction of the new iPhone 6 and iPhone 6 plus in the market, there has not been enough clarity about all the images that need to be included while packaging applications for iPhone 6 and iPhone 6 plus. The following table lists combination of launch images that can be provided to have a properly working application.

 

Devices Resolution  (pixels) Launch image name Orientation

iPhone

iPhone4
(non-retina)
640×960 Default~iphone.png Portrait
iPhone 4,4s 640×960 Default@2x~iphone.png Portrait
iPhone 5,5c,5s 640×1136 Default-568h@2x~iphone.png Portrait
iPhone 6 750×1334 Default-375w-667h@2x~iphone.png Portrait
iPhone 6+ 1242×2208 Default-414w-736h@3x~iphone.png Portrait
iPhone 6+ 2208×1242 Default-Landscape-414w-736h@3x~iphone.png Landscape

iPad

iPad 1,2 768×1024 Default-Portrait~ipad.png Portrait
iPad 1,2 768×1024 Default-PortraitUpsideDown~ipad.png Upside down portrait
iPad 1,2 1024×768 Default-Landscape~ipad.png Left landscape
iPad 1,2 1024×768 Default-LandscapeRight~ipad.png Right landscape
iPad 3,Air 1536×2048 Default-Portrait@2x~ipad.png Portrait
iPad 3,Air 1536×2048 Default-PortraitUpsideDown@2x~ipad.png Upside down portrait
iPad 3,Air 2048×1536 Default-LandscapeLeft@2x~ipad.png Left landscape
iPad 3,Air 2048×1536 Default-LandscapeRight@2x~ipad.png Right landscape

Number of images to include may vary according to the application requirement. If an application is built only for an iPhone, then iPad images can be skipped and vice versa.

On iPhone 6 and iPhone 6 plus, newly introduced display modes (Standard and Zoomed) makes the situation a bit tricky. In Standard mode, both devices display launch image as per the table shown above. In zoomed mode, however, the launch image of its predecessor device is displayed, which means on iPhone 6 plus, image meant for iPhone 6 i.e. Default-375w-667h@2x~iphone.png is displayed, likewise  on iPhone 6 launch image of iPhone 5 is displayed.

Launch Images

 


How to package launch images:

To include launch images in your application, all launch images are required to be placed at the top-most level or base location of your project hierarchy. For example if the base location is the src folder, then all launch images should be placed as shown in the following screenshot.

Demo Project

Project hierarchy

 

However, if you wish to package your iOS application using the command line then launch images can be added as assets in packaging command. For example, to package a Demo app with all iPhone launch images then the same can be done using the following command.

adt -package -target <target> -provisioning-profile <Profile> -storetype pkcs12 -keystore <Certificates.p12> -storepass <password> Demo.ipa Demo-app.xml Demo.swf  Default~iphone.png Default@2x~iphone.png Default-568h@2x~iphone.png Default-375w-667h@2x~iphone.png Default-414w-736h@3x~iphone.png Default-Landscape-414w-736h@3x~iphone.png


Known Issues:

Currently the following known issues exist with launch images in Adobe AIR SDK version 17.0.0.123.

  1. 3945071 : [iPhone 6 +] An inverted launch image is displayed for a split second when the device is kept at rotated right Landscape orientation (Aspect Ratio is landscape and Auto Orients is false).
  2. 3945046 : [iPhone 6 +] An inverted launch image is displayed, if the device is kept in upside-down position and (Auto orient is true and Aspect ratio landscape).
  3. 3945056 : [iPhone 6 +] If a landscape image is not provided for iPhone 6 +, Stretched Portrait launch image is displayed when application is launched in landscape mode.

For more information on iOS Launch image you can refer to Apple’s iOS Human Interface Guidelines.

Versioning of multiple APKs for Android

Recently, with AIR 14, we announced x86 support for AIR applications. In this article, we explain how should developers manage the binary upload on Google Play Store for ARM and x86 binaries. Android devices are available with three kind of architectures – ARM, x86 and devices which support both x86 and ARM architectures (Eg: Samsung Galaxy Tab 3 10.1). AIR SDK (14.0.0.125 beta onwards) allows developers to create separate APK files for ARM and x86 architectures. And Google Play Developer console provides CPU architecture (ABI) as a filter criteria to support multiple APKs for the same application. The way Adobe AIR developers should make use of this filter criteria would depend on the packaging mode – captive or shared.

 

For Apps packaged with Captive mode

Please take a look at the following documentation. AIR developers should follow the same guidelines, as are mentioned for native applications.

http://developer.android.com/google/play/publishing/multiple-apks.html

Assigning a higher versionNumber  (in application descriptor) for the x86 version of apk would ensure that the Google Play serves x86 binary to devices with both x86 and ARM support,  thereby resulting in better performance.

 

For Apps packaged with Shared mode

After the recent release of x86 support in AIR, Play Store will have two different binaries for AIR Runtime app– one for ARM devices, and another for x86 devices. For devices which can run both, ARM binary version would be preferred because that used to get downloaded even before we introduced x86 support. And we plan to continue with the same preference to ensure that shared apps dependent on AIR runtime aren’t affected. To align with AIR Runtime app, applications packaged in shared mode should also keep their x86 based binary with lower versionNumber. With this approach, if you face any performance related issues on devices which support both the processors, then you can opt for captive mode of packaging.

The table below summarizes what version gets downloaded on device with different processors type.

  ARM Device x86 Device Device supporting both x86 and ARM
Runtime.apk ARM version x86 version ARM version
Captive App ARM version x86 version x86 version
Shared App ARM version x86 version ARM version

-Thanks

Multiple ANEs and conflicting resources

AIR 4.0 and later supports packaging of multiple JAR files in an ANE. That allows packaging of third party libraries and their corresponding resources an ANE.

The resources bundled in an ANE or any other library in the ANE can be accessed by R* method, and this document provides all the details.

This post talks about a scenario where multiple ANEs are used in an app and if two or more of the ANEs use same JAR file as a dependency (packagedDependency).  It is not possible to create such an app, and the packager fails with following error –

unexpected failure: duplicate entry: /R.class

This is expected because when the packager picks up resources of all the ANEs, and finds that two or more ANEs are using a same resource, the step to convert *.java to *.class file fails with a duplicate entry error. This is something which the packager cannot resolve by itself, and the developer has to step in.

If you face this packaging error, you need to remove the common JAR from all of the ANEs but one, to ensure that the packager finds a single copy of every JAR file as input.

Here is an example –

Suppose there are two ANEs used in an app i.e. example1.ane and example2.ane. Both of them use a common library, say commonlibrary.jar, and its resources, say, common-lib-res. If you try to package the app with these ANEs, ADT throws an error –

unexpected failure: duplicate entry: com.common.example.lib/R.class

To resolve the issue, you need to follow these steps (eg. is for a Mac) –

1. Copy example1.ane in a temp folder.

2. Unzip example.ane (run command ‘unzip example1.ane‘)

3. Remove the commonlibrary.jar from the package (i.e. from unzipped content of the ANE).

4. Remove the corresponding resources of commonlibrary.jar (i.e. “common-lib-res“) from the package.

5. In platform.xml, delete the entry for commonlibrary.jar from the tag and delete the entry of the common-lib-res from the tag.

6. Zip back contents of package to ANE –

  • zip –r –D example1.zip META-INF catalog.xml library.swf mimetype
  • rm –rf example1.ane META-INF catalog.xml library.swf mimetype
  • mv example1.zip example1.ane

Use this new temp/example1.ane and existing example2.ane to package the APK file. You should not see any packaging or runtime error now.

Hope that helps! :)

Preventing Automatic Cloud Backup on iOS devices

According to the Apple guidelines, data that can be downloaded again or regenerated shall be stored in the <APPLICATION_HOME>/Library/Caches directory. So, with AIR 3.6, a new static property, File.cacheDirectory has been introduced, which points to this directory. Files stored in this directory are not backed up on the iCloud. Examples of files you should put in the Caches directory include database cache files and downloadable content, such as that used by magazine, newspaper, and map applications. On Mac OSX and Android, File.cacheDirectory points to the Caches directory ( <APPLICATION_HOME>/Library/Caches on Mac and <APPLICATION_HOME>/caches directory on Android). While on Windows, it points to the parent directory being used by File.createTempDirectory.

var myCacheFile: File = File.cacheDirectory.resolvePath("cacheFile.txt");

Continue reading…

Changed behavior of Shared Object on iOS in AIR 3.5

With AIR 3.5 the path of shared objects changed than it used to be in AIR 3.4, following illustrates the difference between paths:
In AIR 3.4:
AppName/Library/Application Support/com.namecompany.name/Local Store/ #SharedObjects/Filename.swf
where Filename.swf comes from the <Filename> tag of app-xml.

In AIR 3.5:
AppName/Library/Application Support/com.namecompany.name/Local Store/ #SharedObjects/Content.swf
where Content.swf comes from the <Content> tag of app-xml which contains
the name of root SWF of app.

This issue is fixed in 3.6(labs), so when user will update his/her app from AIR 3.4 to 3.6, then application will not lose any data which is stored with shared object. While any new App which will be published with next release of AIR will have shared object path:
AppName/Library/Application Support/com.namecompany.name/Local Store/ #SharedObjects/Content.swf

Workaround for AIR 3.5:

For those app-developers who are going to publish their app with AIR 3.5 there is a workaround for them.Since now shared object path is taken from tag <Content> rather than tag <Filename> so you can rename your root SWF to Filename.swf and also provide the same to tag. For example:
In AIR 3.4 :
<Filename>MysharedObject</Filename>
<Content>Root.swf</Content>

Now in AIR 3.5, rename it like following:
<Filename>MysharedObject</Filename>
<Content>MysharedObject.swf</Content>

and also rename Root.swf to MysharedObject.swf.
By this way the data of the app will be saved when it will be updated from AIR 3.4 to AIR 3.5.

We would like to hear your feedback, please let us know if you face any issues.