Build offline apps with new PowerApps capabilities

When building mobile apps, one of the most common scenarios app makers face is how to enable their users be productive in situations where there is limited or no connectivity at all. This has been one of the most requested features for PowerApps to allow running apps while being disconnected and to provide some support for offline data caching. In this release of PowerApps, we are delivering the first set of improvements for app makers to achieve that by enabling:

  1. Launching the PowerApps mobile player app offline
  2. Running apps while being offline
  3. Determine when your app is online or offline or in a metered connection by using the Connection signal object.
  4. Leverage existing formulas such as LoadData and SaveData for basic data storage while offline.

 

How to build offline capable apps

The first thing to discuss is how PowerApps applications access data. The primary mechanism for PowerApps applications to consume data is through a set of connectors provided by the platform such as SharePoint, Office 365 and the Common Data Service. You can also build your own custom connectors that can allow you to build any custom logic and capabilities as well as run them anywhere (such as using Azure Functions). The connectors are accessed over the internet using HTTPS which means your users will need to be online for them to access this data or functions that they offer.

PowerApps-Connectors

 

Handling offline data

One of the interesting aspect of PowerApps is that it offers a set of capabilities and formulas that allow you to filter, search, sort, aggregate, insert and manipulate data that is consistent regardless of the data source such as if you are using a SQL database, a SharePoint List, a Common Data Service entity, or even collections that are locally stored the device. This allows us not only to easily build applications that can be retargeted to use a different backend but also that can be modified to use local collections instead with almost no changes to the logic. When dealing with offline data, local collections will be the primary mechanism that PowerApps offers today.

 

What we’ll be building

To keep the focus on the offline aspects and showing some of these new capabilities we are going to keep the scenario very simple. In this case, we are going to build an application that allows you to read twitter posts while being offline as well as tweet while being offline and when the application comes online the tweets will be posted and the local data will be reloaded.

 

At a high level, the application that we will be creating will do the following:

  • On application startup (First screen OnVisible property)
    • If online, we will access directly the connector to fetch the data and use it to populate a local collection
    • If offline, we will load the data from a local cache using LoadData
  • We will allow the user to post tweets, if online we will post directly and refresh the cache
  • Every 5 minutes, if online
    • We will post any tweets that we have in the cache
    • We will refresh the local cache and save it using SaveData

 

Building the Application

  • Create a new Phone App
    • Open PowerApps Studio
    • Click New—>Blank App—>Phone layout

PowerApps-New-Blank-Phone-App

  • Add a Twitter Connector
    • Click Content—>Data sources and choose Add data source on the data sources panel. Click New Connection and select Twitter and click Create. Enter your credentials and create the connection.

PowerApps-Add-New-Twitter-Connector

  • Load the tweets on the startup of the app.
    • Select the OnVisible property on the first screen and type the following expression:
  If(Connection.Connected,
      ClearCollect(LocalTweets, Twitter.SearchTweet("PowerApps", {maxResults: 100}));
      UpdateContext({statusText: "Online data"})
      ,
      LoadData(LocalTweets, "Tweets", true);
      UpdateContext({statusText: "Local data"})
  );
  LoadData(LocalTweetsToPost, "LocalTweetsToPost", true);
  SaveData(LocalTweets, "Tweets")

OfflineLoadData

 

     This formula checks if we are online, if we are it will Load into a “LocalTweets” collection up to 100 tweets with the search term “PowerApps”. If offline, it will load the local cache if available from a file called “Tweets”.

 

  • Add a Flexible height gallery and bind to the LocalTweets collection
    • Insert a new flexible height Gallery by going to Insert—>Gallery—>Blank flexible height
    • Set the 'Items' property to LocalTweets
    • Add four Labels to display the tweet, and set their properties to:
      • ThisItem.TweetText
      • ThisItem.UserDetails.FullName & " @" & ThisItem.UserDetails.UserName
      • "RT: " & ThisItem.RetweetCount
      • Text(DateTimeValue(ThisItem.CreatedAtIso), DateTimeFormat.ShortDateTime)
    • Add an image and set the Image property to ThisItem.UserDetails.ProfileImageUrl

 

  • Add a connection status label
    • Insert a new Label and set its 'Text' property to:
  If (Connection.Connected, "Connected", "Offline")

     This formula checks if the device is online, if it is the text of the label will say “Connected” otherwise “Offline”.

 

  • Add a Text box to compose new tweets
    • Insert a new “NewTweetTextBox” TextBox 
    • Set the Reset property of the NewTextBox to resetNewTweet
  • Add a Button to post the tweet
    • Set the OnSelect of the button to
  If (Connection.Connected,
      Twitter.Tweet("", {tweetText: NewTweetTextBox.Text}),
      Collect(LocalTweetsToPost, {tweetText: NewTweetTextBox.Text});
      SaveData(LocalTweetsToPost, "LocalTweetsToPost")
  );	
  UpdateContext({resetNewTweet: true});
  UpdateContext({resetNewTweet: false})

     This formula checks if we are online, if we are it will tweet the text immediately. If we are not, it will capture the tweet in a “LocalTweetsToPost” collection and save it to the device. Then it resets the text in the text box.

  • Finally, we will add a timer to post any tweets that may be available in the collection pending to be posted.
    • Add a new Timer control
    • Set the Duration property to 300000
    • Set the AutoStart property to true
    • Set the OnTimerEnd to:
  If(Connection.Connected,
      ForAll(LocalTweetsToPost, Twitter.Tweet("", {tweetText: tweetText})); 
      Clear(LocalTweetsToPost);
      Collect(LocalTweetsToPost, {tweetText: NewTweetTextBox.Text});
      SaveData(LocalTweetsToPost, "LocalTweetsToPost");
      UpdateContext({statusText: "Online data"})
  )

 

     This formula verifies if the device is online and if it is it will Tweet all the items that are in the “LocalTweetsToPost” collection. Then it will clear the list.

 

Testing the app

With this release of PowerApps you can now run PowerApps and launch apps even while being offline. However, to be able to run an application you must run it at least once while being online so we can download the app.

  • Run PowerApps in a mobile device
  • Launch the application
  • Notice that the tweets are loaded and that the status label shows online
  • Close PowerApps completely
  • Set the device to Airplane Mode to ensure offline
  • Run PowerApps. As you can see now we allow you to run it offline, and when doing that only applications that you have used in this device will be available
  • Run the application again
  • Notice how it correctly reflects the offline state
  • Write a new Tweet. It will be stored locally in the collection.
  • Exit Airplane Mode, and at this point after 30 seconds once the timer triggers, the tweet will be posted.

 

 

PowerApps-online PowerApps-offline
PowerApps running online PowerApps running offline

 

Further improvements coming

Hopefully this post gives you an idea of some of the initial capabilities that we are adding to enable building basic offline functionality to your application. We will continue to invest on making this scenario not only more streamlined but also more powerful over time. Some of the short term improvements that you can expect to see in a few weeks include:

  • Avoid network calls when offline. Today when you launch PowerApps we still attempt to download the list of apps and other processing that is not necessary while offline. We will remove these which will avoid some delays while running apps offline.
  • We will refresh the list of apps when PowerApps becomes online so that you have a fresh list of apps
  • We will cache the icons used by the apps so that they show properly when offline
  • and others

We hope you will find this capability useful. Over time we will also invest on providing you with better ways to handle conflicts, error handling for network calls, and more.

As always, please provide feedback in our forum and share your examples of offline apps in the PowerApps community blog.