AIR iOS – Background Behavior

On iOS, an application in the foreground moves to background when user presses the home button, or presses sleep/wake button, or the system launches another application. Most applications get suspended on transition to background. Applications that have requested for background execution (such as playing music, location updates, file upload/download) may continue to run for a while longer. In order to improve the device battery life and user’s experience with the foreground application, iOS limits what an application can do in the background.

Default Behavior of AIR application on iOS

By default, an AIR application on iOS gets suspended on entering background, primarily to preserve application’s in-memory state. Thus allowing the application to be quickly re-activated when it is brought to the foreground. When a low-memory condition occurs, the system may purge suspended applications without notice to make more space for the foreground application.

Support for audio playback in background

AIR on iOS provides support for playing audio in the background. Audio playback in the background is required for designing music player sort of application which plays music in both foreground and background. If an application developer wishes to play audio in the background, “UIBackgroundModes” tag with value “audio” needs to be set in the application descriptor.

<iPhone>
    <InfoAdditions>
        <![CDATA[
            <key>UIBackgroundModes</key>
            <array>
                <string>audio</string>
            </array>
        ]]>
    </InfoAdditions>
</iPhone>

 

If UIBackgroundModes is set to audio  then audio from an AIR application would continue playing when it goes to background. In order to conserve battery life, all screen updates would be disabled and application would be throttled down to 4 fps in the background.

Support for location updates in background

AIR on iOS provides support for location updates in the background. Location updates in the background are required for designing navigation based applications which for example give turn by turn directions in both foreground and background and may even speak out the route changes. If an application developer wishes to receive location updates in the background, “UIBackgroundModes” tag with value “location” needs to be set in the application descriptor.

<iPhone>
    <InfoAdditions>
        <![CDATA[
            <key>UIBackgroundModes</key>
            <array>
                <string>location</string>
            </array>
        ]]>
    </InfoAdditions>
</iPhone>

 

If UIBackgroundModes is set to location  then AIR application would continue to receive location updates when application goes to background (event listener for AIR Geo-location APIs should be already added). In order to conserve battery life, all screen updates would be disabled and application would be throttled down to 4 fps in the background. Location services should be used judicially as the location APIs consume significant battery.

In case application developer want to design an application that can speak out the route changes in the background, “UIBackgroundModes” tag with value “location and “audio” needs to be set in the application descriptor.

<iPhone>
    <InfoAdditions>
        <![CDATA[
            <key>UIBackgroundModes</key>
            <array>
                <string>location</string>
                <string>audio</string>
            </array>
        ]]>
    </InfoAdditions>
</iPhone>

Task completion in background

AIR on iOS provides support for executing short task in the background. Task completion in background is required for designing applications were end user starts a long running task like a photo upload or sending an email with attachments and then enters the background. End user would expect that the initiated task would be completed in the background.

If an application developer want to execute short task in the background, executeInBackground property needs to be set to true.

NativeApplication.nativeApplication.executeInBackground = true;

 

One can also query the value of executeInBackground property

trace(NativeApplication.nativeApplication.executeInBackground);

 

Setting executeInBackground property to “true” does not guarantee that application would run in the background for infinite amount of time. iOS imposes an limit on the time up-to which an background task could run, application will be suspended once this time duration has lapsed. If value of executeInBackground property is set to “false”, application will be suspended on entering the background.

Consider a scenario where user starts a image upload operation and application goes to background before complete event is received. In deactivate event handler, application developer can set the executeInBackground property to “true” in case application developer wants upload operation to continue in the background. Whenever complete event is received by the application, executeInBackground property should be set to false, indicating application no longer want to execute in the background.

iOS does not guarantee that application would run in the background for infinite amount of time, there is a possibility that application would be suspended before it’s done with background processing. In this case NativeApplication.Suspend event would be dispatched to the app when it is about to be suspended, so that application developer can save its state. In order to conserve battery life, all screen updates would be disabled and application would be throttled down to 4 fps in the background.

NativeApplication.nativeApplication.executeInBackground property is applicable only on iOS and will fail silently, in case it is not supported on the underlying platform.

Opt out of Background Execution

AIR on iOS provides support for opting out of background execution. Opting out of background execution is required for designing applications that saves its state periodically and hence does not want to be suspended when it enters background. If an application developer wishes to opt out of background execution, “UIApplicationExitsOnSuspend” key with value “true” needs to be set in the application descriptor.

<iPhone>
    <InfoAdditions>
        <![CDATA[
            <key>UIApplicationExitsOnSuspend</key>
            <true/>
        ]]>
    </InfoAdditions>
</iPhone>

 

When UIApplicationExitsOnSuspend key is set to true, application is terminated and purged from memory instead of suspending when application moves to background. If UIApplicationExitsOnSuspend key is not present, or is set to false, the application moves to the background as usual.

18 Responses to AIR iOS – Background Behavior

  1. Pingback: AIR iOS – Background Behavior « eaflash

  2. Florian says:

    Hi nehgupta,

    Thank you for this interesting post.

    I’m developing an AIR app for iOS and facing a problem with the SoundChannel Event.SOUND_COMPLETE event which is not being fired when the app is put in background.

    I have UIApplicationExitsOnSuspend=true and UIBackgroundModes=audio in the manifest, and NativeApplication.nativeApplication.executeInBackground = true but the SOUND_COMPLETE event is fired only when I reopen the app.

    The sound continues to play when in background, but I can’t play a playlist of several sounds, which is the core of my app :(

    I’m compiling with Flex SDK 4.6 / AIR 3.4 and running iOS 6.

    Any info are more than welcome.
    Thank you.

    Regards,
    Florian

    • nehgupta says:

      Could you please confirm the reason for putting UIApplicationExitsOnSuspend=true in the manifest? From your query it seems you want to execute your application in background. UIApplicationExitsOnSuspend=true should be set when application does not want to execute in background. Also confirm if logic for playing next sound (from playlist) is placed in SOUND_COMPLETE event handler.

  3. Florian says:

    Hi nehgupta,

    My mistake, I should have wrote UIApplicationExitsOnSuspend=false.

    Here is my onSoudComplete function:

    static private function soundCompleteHandler( e:Event ):void
    {
    trace( “soundCompleteHandler” );
    playNextTrack();
    }

    Foreground: my code is working well.
    Going to background: the current SoundChannel plays until the end. The SOUND_COMPLETE event is not fired (no trace, no sound)
    Going back to foreground: the event is fired, the trace comes, and the next track is played.

    I also tried to launch a timer and or setTimeout on nativeApplication Event.DEACTIVATE, but they’re also triggered only on re-opening.

    Same behaviour on Android.

    Is that an expected behaviour on iOS/Android or should I does I forgot something?
    If so, does Adobe have plan to improve the backgrounding on mobile?

    Thanks.

    Regards,
    Florian

    • nehgupta says:

      I am getting SOUND_COMPLETE event when app is executed in background. I tried below code with AIR 3.4 + iPhone4 running iOS6.

      ActionScript
      public class TestBackgroundBehavior extends Sprite
      {
      private var sound:Sound;
      private var soundChannel:SoundChannel;

      public function TestBackgroundBehavior()
      {
      stage.addEventListener(Event.DEACTIVATE, onDeactivate);

      sound = new Sound();
      var req:URLRequest = new URLRequest(“sound.mp3″);
      sound.load(req);
      soundChannel = sound.play();
      soundChannel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
      }

      private function onDeactivate(e:Event):void
      {
      trace(“onDeactivate”);
      NativeApplication.nativeApplication.executeInBackground = true;
      }

      private function onSoundComplete(e:Event):void
      {
      trace(“onSoundComplete”);
      }
      }

      Manifest file has namespace 3.4 and UIBackgroundModes is set to audio.

  4. Florian says:

    Ok, I understood something interesting but desappointing.

    If sound Event.OPEN is fired after Event.DEACTIVATE, the SOUND_COMPLETE is fired (by backgrounding the test app right after its execution).

    In fact, the problem is related to the fact I’m using renderMode=gpu…
    If I change the renderMode for cpu, events are fired and following tasks handled.

    Here is the code I used:

    public class TestBackgroundBehaviour extends Sprite
    {
    private var sound:Sound;
    private var soundChannel:SoundChannel;

    public function TestBackgroundBehaviour()
    {
    stage.addEventListener(Event.DEACTIVATE, onDeactivate);

    play();

    }

    private function play():void
    {
    sound = new Sound();
    sound.addEventListener( Event.OPEN, onOpen );

    var req:URLRequest = new URLRequest(“sound.mp3″);
    sound.load(req);

    soundChannel = sound.play();
    soundChannel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
    }

    private function onOpen(e:Event):void
    {
    trace( “Open” );
    }

    private function onDeactivate(e:Event):void
    {
    trace(“onDeactivate”);
    NativeApplication.nativeApplication.executeInBackground = true;
    }

    private function onSoundComplete(e:Event):void
    {
    trace(“onSoundComplete”);
    play();
    }
    }

    Were you aware of that issue using Stage3D?
    Could you investigate to know if there’s any plan to add background support using renderMode=direct or gpu?

    This is definitely crucial for Adobe AIR since not using Starling or Away3D 4 is just impossible on mobile.

    My music app will be a lot more interesting without background audio playing.

    Thanks

  5. Florian says:

    .. a lot LESS interesting…

  6. Florian says:

    nehgupta, could you please reply to my last message?

    Thanks!

    • nehgupta says:

      This limitation is known to us. Execution in background is not allowed on Android and iOS in case renderMode direct or gpu is used in the application. I understand your concern, you might want to raise a feature request for it.

      • Paresh says:

        Hello nehgupta,
        I am concern to know can we create background running application in Android or IOS using Flash Builder 4.6, Air 3.1.
        As I am starting to develop a small reminder application which will update User regarding its IMP reminders which are Set.
        Kindly guide me for the concern to develop this application.

        • nehgupta says:

          With Air3.1, you can do background execution on Android. However on iOS, you can only play audio in background. To utilize full potential of AIR, i would recommend to use the latest SDK.

  7. Florian says:

    It’s maybe know to you, but not to developers.

    It’s now a huge issue for my project and a shame that Adobe did not communicate about that.

    None of these pages mention this limitation:
    - http://www.adobe.com/devnet/air/articles/considerations-air-apps-mobile.html
    - http://help.adobe.com/en_US/air/build/WSfffb011ac560372f7e64a7f12cd2dd1867-8000.html
    - http://forums.adobe.com/message/3956292

    I love Flash, but because of this kind of issues, developers are losing their confidence about keeping to be an AS3 developer or learning a new language.

    Thank you anyway.

  8. Florian says:

    If you are interested in getting background tasking on iOS/Android when using Stage3D, PLEASE VOTE FOR THE FEATURE REQUEST HERE:
    https://bugbase.adobe.com/index.cfm?event=bug&id=3349232

  9. Pingback: AIR iOS – Background Behavior | sewonist.com

  10. frank says:

    There is a way to receive accelerometer data in background like Nike+ with Air for iOS? I would like to do a pedometer and I want it to be active all the time. With Objective C, if you use Core Motion Framework and backgroundMode = location , it’s possible. Is it possible with Air?

  11. frank says:

    Is it possible to receive accelerometer data in background like Nike+ ? I read that it’s possible with Objective-C if we use “Core Motion Framework” and “UIBackgroundModes=location”. With Air, it’s possible to have the same behaviour ? There are some way to receive accelerometer in background?

  12. Pingback: AIR iOS – Background Behavior | TechnoVeille