Создание мобильного приложения Kotlin с помощью Salesforce SDK: синхронизация данных
3 мая 2022 г.Это наш последний пост в нашей серии из трех частей, демонстрирующих, как использовать Salesforce Mobile SDK для создания приложения Android, которое работает с платформой Salesforce. [В нашем первом сообщении] (https://hackernoon.com/building-a-kotlin-mobile-app-with-the-salesforce-sdk) мы показали вам, как подключиться к вашей организации. Наш второй пост показал вам, как редактировать и добавить данные в вашу организацию из вашего приложения. В этом посте показано, как синхронизировать данные из вашей организации Salesforce с мобильным устройством и обрабатывать такие сценарии, как потеря сети. Давайте приступим прямо к делу!
Работа с мобильной синхронизацией
Одним из самых сложных аспектов мобильной разработки является синхронизация данных. Как вы справляетесь с ситуацией, когда вам нужно добавить нового брокера, но вы не в сети? Или что, если два агента обновляют одного и того же брокера — как вы можете справиться с объединением этих двух изменений?
С Salesforce Mobile SDK эти реальные проблемы решаются за вас с помощью системы под названием Mobile Sync. Mobile Sync позволяет сопоставить локальные данные вашего телефона с данными в Salesforce; он также требует, чтобы вы определили операции для выборки и отправки данных — то, что он называет «syncDown» и «syncUp».
Определите форму данных для синхронизации
Чтобы начать работу с Mobile Sync, создайте файл в res/raw
с именем brokerstore.json
:
"супы": [
"soupName": "брокеры",
"индексы": [
{ "путь": "идентификатор", "тип": "строка"},
{ "путь": "имя", "тип": "строка"},
{ "путь": "Title__c", "тип": "строка"},
{ "путь": "Phone__c", "тип": "строка"},
{ "путь": "Mobile_Phone__c", "тип": "строка"},
{ "путь": "Email__c", "тип": "строка"},
{ "путь": "Picture__c", "тип": "строка"},
{ "путь": "local", "тип": "строка"},
{ "путь": "locally_created", "тип": "строка"},
{ "путь": "locally_updated", "тип": "строка"},
{ "путь": "locally_deleted", "тип": "строка"},
{ "путь": "sync_id", "тип": "целое число"}
Этот файл определяет форму данных на вашем телефоне, а также некоторые дополнительные метаданные, необходимые для синхронизации.
Затем создайте файл с именем brokersync.json
:
"синхронизирует": [
"syncName": "syncDownBrokers",
"syncType": "syncDown",
"soupName": "брокеры",
"target": {"type":"soql", "query":"ВЫБЕРИТЕ Имя, Заголовок__c, Телефон__c, Мобильный_Телефон__c, Электронная почта__c, Изображение__c ОТ Broker__c LIMIT 10000"},
"опции": {"режим слияния":"ПЕРЕЗАПИСАТЬ"}
"syncName": "syncUpBrokers",
"syncType": "syncUp",
"soupName": "брокеры",
"target": {"createFieldlist":["Имя", "Заголовок__c", "Телефон__c", "Мобильный_телефон__c", "Электронная почта__c", "Изображение__c"]},
"options": {"fieldlist":["Id", "Name", "Title__c", "Phone__c", "Mobile_Phone__c", "Email__c", "Picture__c"], "mergeMode":"LEAVE_IF_CHANGED"}
Это операции, которые Mobile Sync будет использовать при синхронизации данных вверх и вниз.
Код для завершения процесса Mobile Sync зависит от нескольких факторов, например от того, когда вы хотите выполнить синхронизацию, а также от подключения к циклу событий Android, когда устройство теряет (и восстанавливает) подключение.
Следующие примеры кода покажут вам полный пример того, что должно произойти, чтобы синхронизация заработала, но их следует рассматривать как концепции высокого уровня, а не обязательно готовый к работе код корпоративного уровня.
Настроить периодическую синхронизацию
С учетом сказанного давайте посмотрим, как реализовать синхронизацию. Во-первых, добавьте эту строку в конец нашего метода onResume(client: RestClient)
в MainActivity.kt
:
НастройкаПериодическаяСинхронизация();
Далее мы добавим новую переменную и новую функцию в класс MainActivity:
частное значение SYNC_CONTENT_AUTHORITY =
"com.salesforce.samples.mobilesyncexplorer.sync.brokersyncadapter"
приватная забава setupPeriodicSync() {
val account = MobileSyncSDKManager.getInstance().userAccountManager.currentAccount
ContentResolver.setSyncAutomatically (учетная запись, SYNC_CONTENT_AUTHORITY, правда)
ContentResolver.addPeriodicSync(
аккаунт, SYNC_CONTENT_AUTHORITY,
Связка.ПУСТОЙ, 10
Поскольку мы используем ContentResolver
в нашей функции, давайте обязательно импортируем его, добавив эту строку вместе с другими операторами импорта в верхней части MainActivity.kt
:
import.android.content.ContentResolver
Мы определили два метода, запускающих синхронизацию. setupPeriodicSync
будет запускать синхронизацию каждые 10 секунд. Это слишком часто для производственной среды, но мы установим его таким образом в демонстрационных целях.
Сопоставление операций синхронизации с нашими данными и пользовательским интерфейсом
Следующие несколько примеров кода мы покажем сразу, а потом обсудим, что они делают.
В app/java/com.example.sfdc создайте новый файл с именем BrokerSyncAdapter.kt и вставьте в него следующие строки:
пакет com.example.sfdc
импортировать android.accounts.Account
импортировать android.content.AbstractThreadedSyncAdapter
импортировать android.content.ContentProviderClient
импортировать android.content.Context
импортировать android.content.SyncResult
импортировать android.os.Bundle
импортировать com.salesforce.androidsdk.accounts.UserAccount
импортировать com.salesforce.androidsdk.accounts.UserAccountManager
импортировать com.salesforce.androidsdk.app.SalesforceSDKManager
импортировать com.example.sfdc.BrokerListLoader
класс BrokerSyncAdapter
контекст: контекст?, автоинициализация: логическое значение,
allowParallelSyncs: логическое значение
):
AbstractThreadedSyncAdapter(context, autoInitialize, allowParallelSyncs) {
переопределить удовольствие onPerformSync(
account: Account, extras: Bundle, полномочия: String,
поставщик: ContentProviderClient, syncResult: SyncResult
val syncDownOnly = extras.getBoolean (SYNC_DOWN_ONLY, ложь)
val sdkManager = SalesforceSDKManager.getInstance()
val accManager = sdkManager.userAccountManager
если (sdkManager.isLoggingOut || accManager.authenticatedUsers == null) {
возврат
если (учетная запись != ноль) {
val user = sdkManager.userAccountManager.buildUserAccount(учетная запись)
val contactLoader = BrokerListLoader (контекст, пользователь)
если (syncDownOnly) {
contactLoader.syncDown()
} еще {
contactLoader.syncUp() // выполняет синхронизацию, а затем синхронизацию вниз
сопутствующий объект {
// Ключ для набора дополнений
константное значение SYNC_DOWN_ONLY = "syncDownOnly"
Теперь в той же папке создайте BrokerListLoader.kt со следующими строками:
пакет com.example.sfdc
импортировать android.content.AsyncTaskLoader
импортировать android.content.Context
импортировать android.content.Intent
импортировать android.util.Log
импортировать com.salesforce.androidsdk.accounts.UserAccount
импортировать com.salesforce.androidsdk.app.SalesforceSDKManager
импортировать com.salesforce.androidsdk.mobilesync.app.MobileSyncSDKManager
импортировать com.salesforce.androidsdk.mobilesync.manager.SyncManager
импортировать com.salesforce.androidsdk.mobilesync.manager.SyncManager.MobileSyncException
импортировать com.salesforce.androidsdk.mobilesync.manager.SyncManager.SyncUpdateCallback
импортировать com.salesforce.androidsdk.mobilesync.util.SyncState
импортировать com.salesforce.androidsdk.smartstore.store.QuerySpec
импортировать com.salesforce.androidsdk.smartstore.store.SmartSqlHelper.SmartSqlException
импортировать com.salesforce.androidsdk.smartstore.store.SmartStore
импортировать org.json.JSONArray
импортировать org.json.JSONException
импортировать java.util.ArrayList
класс BrokerListLoader (контекст: контекст?, учетная запись: UserAccount?):
AsyncTaskLoader?>(контекст) {
частный val smartStore: SmartStore
частный val syncMgr: SyncManager
переопределить удовольствие loadInBackground(): List
если (!smartStore.hasSoup(BROKER_SOUP)) {
вернуть ноль
val querySpec = QuerySpec.buildAllQuerySpec(
BROKER_SOUP,
"Имя", QuerySpec.Order.ascending, LIMIT
val результаты: JSONArray
брокеры val: MutableList
пытаться {
результаты = smartStore.query(querySpec, 0)
for (i в 0 до results.length()) {
Brokers.add(results.getJSONObject(i).getString("Имя"))
} поймать (e: JSONException) {
Log.e(TAG, "При анализе произошло исключение JSONException", e)
} поймать (e: Исключение SmartSqlException) {
Log.e(TAG, "При извлечении данных произошло исключение SmartSqlException", e)
брокеры по возврату
@Синхронизированный
забавная синхронизация () {
пытаться {
syncMgr.reSync(
SYNC_UP_NAME
) {синхронизация ->
если (SyncState.Status.DONE == sync.status) {
syncDown()
} поймать (e: JSONException) {
Log.e(TAG, "При анализе произошло исключение JSONException", e)
} поймать (e: MobileSyncException) {
Log.e(TAG, "При попытке синхронизации произошло исключение MobileSyncException", e)
- Извлекает последние записи с сервера.
@Синхронизированный
весело syncDown () {
пытаться {
syncMgr.reSync(
SYNC_DOWN_NAME
) {синхронизация ->
если (SyncState.Status.DONE == sync.status) {
fireLoadCompleteIntent()
} поймать (e: JSONException) {
Log.e(TAG, "При анализе произошло исключение JSONException", e)
} поймать (e: MobileSyncException) {
Log.e(TAG, "Произошло исключение MobileSyncException при попытке синхронизации", e)
частное развлечение fireLoadCompleteIntent() {
val намерение = намерение (LOAD_COMPLETE_INTENT_ACTION)
SalesforceSDKManager.getInstance().appContext.sendBroadcast(намерение)
сопутствующий объект {
const val BROKER_SOUP = "брокеры"
константное значение LOAD_COMPLETE_INTENT_ACTION =
"com.salesforce.samples.mobilesyncexplorer.loaders.LIST_LOAD_COMPLETE"
private const val TAG = "BrokerListLoader"
private const val SYNC_DOWN_NAME = "syncDownBrokers"
частная константа val SYNC_UP_NAME = "syncUpBrokers"
частная константа LIMIT = 10000
в этом {
val sdkManager = MobileSyncSDKManager.getInstance()
smartStore = sdkManager.getSmartStore(учетная запись)
syncMgr = SyncManager.getInstance(учетная запись)
// Настраиваем схему, если нужно
sdkManager.setupUserStoreFromDefaultConfig()
// Настраиваем синхронизацию, если нужно
sdkManager.setupUserSyncsFromDefaultConfig()
Что мы только что сделали? У каждого файла есть определенная роль, и хотя объекты и поля, безусловно, будут разными для вашего приложения, функции и философия этих классов одинаковы:
BrokerListLoader
отвечает за сопоставление операций синхронизации, которые вы определили вbrokersync.json
, с кодом Kotlin, который фактически будет выполнять работу. Обратите внимание, что существуют методы syncUp и syncDown, которые используют SyncManager из Mobile SDK для загрузки файлов JSON и обратной связи с Salesforce.
BrokerSyncAdapter
лучше всего рассматривать как код, отвечающий за планирование синхронизации. То есть это точка входа дляBrokerListLoader
, и ее можно вызывать элементами пользовательского интерфейса (например, во время нажатия кнопки обновления) или системными событиями Android (например, потерей подключения).
Наконец, нам нужно добавить одну строку в наш файл AndroidManifest.xml
(в app/manifests
). Для нашей новой функции синхронизации потребуются специальные разрешения Android, которые мы просим пользователя разрешить при установке приложения во время выполнения. Добавьте следующую строку с WRITE_SYNC_SETTINGS
в конец вашего манифеста:
Проверка синхронизации
Наш последний шаг — проверить, работает ли мобильная синхронизация. Когда эмулятор запущен, вы должны войти в систему и увидеть список брокеров. Этот список должен отражать список брокеров, который вы видите в своем веб-браузере на локальном компьютере. В веб-браузере отредактируйте имя одного из брокеров и сохраните это изменение.
Затем в эмуляторе вы можете выключить телефон или переключиться на другое приложение, а затем снова переключиться на свое sfdc-mobile-app
. Вы должны увидеть список имен брокеров, обновленный с учетом изменений, внесенных вами в браузере:
И это все! Опять же, это всего лишь базовый строительный блок, на котором вы можете учиться. Всего за 150 строк кода мы разработали решение для довольно сложной последовательности движущихся частей:
- Сопоставление пользовательских объектов Salesforce с JSON
- Настройка таймера для периодической синхронизации данных между организацией Salesforce и мобильным устройством.
- Обработка ошибок (и устранение проблем) при подключении к сети
Вывод
Salesforce Mobile SDK чрезвычайно упрощает подключение мобильных устройств к данным Salesforce. В этом посте вы узнали, как запрашивать и обрабатывать данные со своего телефона, и увидели, как результаты мгновенно отражаются в Salesforce. Вы также узнали о Mobile Sync и его роли в предупреждении проблем с подключением.
И все же, со всей этой информацией, есть еще намного больше, что может сделать Salesforce Mobile SDK. Взгляните на полную документацию по работе с SDK. Или, если вы предпочитаете больше программировать, есть множество руководств по Trailhead , которые помогут вам занять себя. Нам не терпится увидеть, что вы строите!
Оригинал