Building a Kotlin Mobile App with the Salesforce SDK

Nowadays, users expect mobile apps to act as counterparts to the websites and platforms they use on the web. Mobile applications give users the ability to carry their data with them, granting them the flexibility to interact with platforms wherever they go. This usability makes sense, and we are all familiar with it.

Developing a mobile experience that’s seamlessly integrated with the functionality of your website can be intimidating. For starters, how should you store and retrieve data if the mobile app loses connectivity? What happens when two mobile users try to update the same data at the same time? How can you just make sure your app’s data is in sync, given that it has limited storage space?

In this series, we’ll take a look at the Salesforce Mobile SDK, a toolkit that addresses many of these technical challenges for developers building apps for Android or iOS. The Salesforce Mobile SDK handles data synchronization, offline storage, notifications, authentication, and many more essential details. To highlight some of these features, we’ll build an app that accesses real Salesforce data.

On the Salesforce end, we’ll set up an org with a pre-populated app that uses custom objects. In this first post of the series, we’ll cover how to get our mobile app to display our records. In Part Two, we’ll cover how to create and update records in our list. Finally, in Part Three, we’ll learn how to work with the SDK and the Salesforce APIs to synchronize data between the desktop and mobile environments.

Although the app will be written in Kotlin and run on Android, the fundamental concepts apply to iOS. We’re choosing Kotlin for the same reasons the Android platform recommends it: it’s faster to write in, offers more code safety than Java, and boosts productivity with its expressiveness.

Prerequisites

Before we begin, install the following software on your machine:

  1. Salesforce CLI — this is a CLI designed by Salesforce to simplify platform interactions.
  2. Kotlin (>= 1.4)
  3. A recent version of Node (>= 12.0)
  4. All Android-specific requirements listed here
  5. Git

Since we’re just exploring the SDK right now, it’s important that whatever we build doesn’t affect your “real” production Salesforce organization (also called “org” for short). Therefore, we’re going to create a separate free Developer Edition org which our app can interact with.

First, sign up for your Developer Edition. Take note of your username, as you’ll need it in a moment. After you’ve verified your email address and your org is available for use, go ahead and follow these instructions to clone the dreamhouse-lwc project onto your computer, and then upload it to your new org using sfdx, the Salesforce CLI.

The Dreamhouse app is a sample Salesforce application that lists realtors and their associated properties. After following the instructions linked above, the app will contain sample data which we can interact with.

To see the app, enter the following command to open up your org:

sfdx force:org:open -u <username-or-alias>

Note: When you authorized your org with the command line, you were instructed to create an alias. This is interchangeable with username to pass into the -u parameter above.

This opens a browser window and takes you to your Salesforce org. Click on the App Launcher icon (the grid of dots) in the upper left corner, and select the Dreamhouse app. As you explore it, you should see information on properties, brokers, and more. This app and its corresponding custom objects represent the platform our mobile app will interact with.

Setting up the Android Studio IDE

We will use the Android Studio IDE for this Kotlin app. This page lists everything you need to do to prepare your computer for Android development. Understanding this documentation is essential for building your Android app, but here’s a brief overview of what you need to do:

First, install forcedroid, an npm package that assists you with Salesforce mobile app development, by running the following in the terminal:

npm install -g forcedroid

Next, run forcedroid create and provide the following values:

  • The application type is native_kotlin
  • The application name is sfdc-mobile-app
  • The package name is com.example.sfdc
  • The organization name is Dreamhouse
  • Set the output directory to the current directory

Open Android Studio and navigate to the directory where you created this app. Create an Android Virtual Device—an emulator—and download the API version 30 (R) system image onto it.

To ensure that everything is set up properly, click the Run button, which is the green triangle at the top bar. A phone emulator should pop up and boot with Android. You’ll be greeted with a Salesforce login screen.

Let’s test that we can communicate with our Developer Edition org. In the top right corner of the form, click the menu icon, then select Change Server:

After that, click Add New Connection.

Earlier, when we called sfdx force:org:open in the command line, a URL was displayed. Copy the entire domain that was displayed, using that as your custom domain. For example, it might look something like this: flow-app-2586-dev-ed.cs4.my.salesforce.com. Paste that in as the value of your new connection.

After that, return to the login screen and log in with your username and password. Your username and password are the same as those you use to log into your Developer Edition org. Once you’ve authenticated successfully, you’ll be ready to write the app!

Displaying Data

Since our Dreamhouse app already contains custom objects, our first step will be to display some of that same data in the mobile app. To do that, we’ll authenticate the Salesforce mobile app to Salesforce.com, and then fetch a list of brokers.

Let’s take a brief look at what forcedroid did for us. Inside the app/java/com.example.sfdc folder, it created two files: MainActivity.kt and MainApplication.kt. You can read up on the specifics of these files. However, in a nutshell, MainApplication sets up the Salesforce Mobile SDK; MainActivity is the app’s “home page,” and is responsible for all other UI, navigation, and functionality.

You may have noticed the option to click on some buttons and fetch data when you launched the app. While it’s nice that the Mobile SDK sets up an environment where you can get up and running, that’s no fun if we—intrepid developers that we are—want to build something from scratch! Let’s make a few changes to the files we’ve been given to start exploring the SDK.

Let’s start with the view first. Open up app/res/layout/main.xml, then switch to the Code view. Paste in the following XML layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="?android:colorBackground"
  android:id="@+id/root" >

  <include layout="@layout/header" />

  <ListView android:id="@+id/brokers_list"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="?android:colorBackground"
     android:textColor="?android:textColor"/>
</LinearLayout>

Here, we’ve set up a simple list with the id brokers_list, which will act as the container for our brokers. To make accessing these views easier in code, we’re going to set up a feature called View Binding. In the left pane, expand the Gradle scripts category, and select the build.gradle file for your module.

Within the Android namespace, add these lines to enable View Binding:

buildFeatures {
  viewBinding true
}

Now, in MainActivity.kt, we need to make two changes: We need to associate the layout ID with a variable we can use in Kotlin, and we need to make a request to display a list of brokers. First, we need to import our layouts; add these to the top of the file near the other import statements:

import com.example.sfdc.databinding.MainBinding

Then, initialize a view variable within the MainActivity class:

class MainActivity : SalesforceActivity() {

   // …
   
   private lateinit var mainViewBinding: MainBinding

   // …

In the onCreate function, change the final line which reads setContentView(R.layout.main)

to these lines:

mainViewBinding = MainBinding.inflate(layoutInflater)
val view = mainViewBinding.root
// Setup view
setContentView(view)

This has now set a value for our mainViewBinding variable. We can now populate our layouts with logic defined in our code. Replace the existing onResume functions with these lines:

override fun onResume() {
   // Hide everything until we are logged in
   mainViewBinding.root.visibility = View.INVISIBLE

   // Create list adapter
   listAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, ArrayList<String>())
   mainViewBinding.brokersList.adapter = listAdapter

   super.onResume()
}

override fun onResume(client: RestClient) {
   // Keeping reference to rest client
   this.client = client

   // Show everything
   mainViewBinding.root.visibility = View.VISIBLE
   sendRequest("SELECT Name FROM Broker__c")
}

mainViewBinding uses the IDs we defined in the layout, while sendRequest makes a query to Salesforce to fetch the records for you. Go ahead and launch the app; you will receive a list of these broker names—front and center!

Notice what we haven’t done here. We didn’t write any code to do the Salesforce authentication, and our business logic to fetch records was already abstracted away for us by the Mobile SDK. All we had to do was design the layout, and create a new query that matched what we wanted to get out of the database.

To Be Continued…

This is a great stopping point to reflect on what we’ve done:

  • We set up a new Developer Edition org, and pushed a sample app (with sample data) called Dreamhouse
  • We set up an Android emulator and the Salesforce Mobile SDK
  • We built an app, logged into our org, and fetched data from it

In the Part Two of this series, we’ll learn how to edit and insert data from the app to our org. Stay tuned!

.

Leave a Comment