Создание мобильного приложения Kotlin с помощью Salesforce SDK: синхронизация данных

Создание мобильного приложения 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 = ArrayList()


пытаться {


результаты = 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.xmlapp/manifests). Для нашей новой функции синхронизации потребуются специальные разрешения Android, которые мы просим пользователя разрешить при установке приложения во время выполнения. Добавьте следующую строку с WRITE_SYNC_SETTINGS в конец вашего манифеста:





Проверка синхронизации


Наш последний шаг — проверить, работает ли мобильная синхронизация. Когда эмулятор запущен, вы должны войти в систему и увидеть список брокеров. Этот список должен отражать список брокеров, который вы видите в своем веб-браузере на локальном компьютере. В веб-браузере отредактируйте имя одного из брокеров и сохраните это изменение.



Затем в эмуляторе вы можете выключить телефон или переключиться на другое приложение, а затем снова переключиться на свое sfdc-mobile-app. Вы должны увидеть список имен брокеров, обновленный с учетом изменений, внесенных вами в браузере:



И это все! Опять же, это всего лишь базовый строительный блок, на котором вы можете учиться. Всего за 150 строк кода мы разработали решение для довольно сложной последовательности движущихся частей:


  • Сопоставление пользовательских объектов Salesforce с JSON

  • Настройка таймера для периодической синхронизации данных между организацией Salesforce и мобильным устройством.

  • Обработка ошибок (и устранение проблем) при подключении к сети

Вывод


Salesforce Mobile SDK чрезвычайно упрощает подключение мобильных устройств к данным Salesforce. В этом посте вы узнали, как запрашивать и обрабатывать данные со своего телефона, и увидели, как результаты мгновенно отражаются в Salesforce. Вы также узнали о Mobile Sync и его роли в предупреждении проблем с подключением.


И все же, со всей этой информацией, есть еще намного больше, что может сделать Salesforce Mobile SDK. Взгляните на полную документацию по работе с SDK. Или, если вы предпочитаете больше программировать, есть множество руководств по Trailhead , которые помогут вам занять себя. Нам не терпится увидеть, что вы строите!



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE