Создание мобильного приложения Kotlin с помощью Salesforce SDK: редактирование и создание данных — часть 2

Создание мобильного приложения Kotlin с помощью Salesforce SDK: редактирование и создание данных — часть 2

6 марта 2022 г.

Во второй части нашей серии, состоящей из трех частей, мы продолжаем опираться на основы разработки под Android с помощью Salesforce Mobile SDK. [В первой части] (https://hackernoon.com/building-a-kotlin-mobile-app-with-the-salesforce-sdk) мы рассмотрели настройку проекта и создание макета, который извлекает данные из Salesforce, используя Kotlin в качестве наш язык программирования по выбору.


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


Редактирование данных


Установив представление, давайте посмотрим, как мы можем редактировать данные. В идеале мы хотим сохранить тот же формат списка, но сделать его таким, чтобы, если пользователь коснется имени, он мог его отредактировать. Затем эти изменения должны быть отправлены обратно в Salesforce.


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


Как и прежде, начнем с макета. Создайте файл в app/res/layout с именем broker_item.xml и вставьте в него следующие строки:



<линейный макет


xmlns:android="http://schemas.android.com/apk/res/android"


андроид: ориентация = "вертикальный"


Android: layout_width = "fill_parent"


андроид: layout_height="fill_parent">


<EditText android:id="@+id/broker_field"


Android: layout_width = "fill_parent"


android:layout_height="wrap_content"



Затем создайте файл в app/java/com.example.sfdc с именем BrokerListAdapter.kt и вставьте в него это:


пакет com.example.sfdc


импортировать android.content.Context;


импортировать android.text.Editable;


импортировать android.text.TextWatcher;


импортировать android.view.LayoutInflater;


импортировать android.view.View;


импортировать android.view.ViewGroup;


импортировать android.widget.ArrayAdapter;


импортировать android.widget.EditText;


импортировать com.salesforce.androidsdk.rest.BrokerItemBinding


импортировать com.salesforce.androidsdk.rest.ApiVersionStrings


импортировать com.salesforce.androidsdk.rest.RestClient


импортировать com.salesforce.androidsdk.rest.RestRequest


импортировать com.salesforce.androidsdk.rest.RestResponse


класс BrokerListAdapter : ArrayAdapter {


внутренний переменный контекст: Контекст


Частный поздний вход var brokerItemBinding: BrokerItemBinding


частный клиент var: RestClient? = ноль


частный val nameToId: MutableMap = mutableMapOf()


конструктор (контекст: контекст): супер (контекст, R.layout.broker_item, ArrayList(0)) {


этот.контекст = контекст;


весело setClient (клиент: RestClient?) {


this.client = клиент


забавная карта (имя: строка, идентификатор: строка) {


this.nameToId.put(имя, идентификатор)


переопределить fun getView (position: Int, convertView: View?, parent: ViewGroup): View {


val inflater = контекст


.getSystemService(Context.LAYOUT_INFLATER_SERVICE) как LayoutInflater


BrokerItemBinding = BrokerItemBinding.inflate(inflate)


val rowView: View = inflater.inflate(R.layout.broker_item, parent, false)


значение BrokerField = BrokerItemBinding.brokerField


var item = getItem(позиция)


var brokerId = nameToId.get(item)


val поля: MutableMap = mutableMapOf()


BrokerField.setText (элемент)


BrokerField.addTextChangedListener (объект: TextWatcher {


переопределить удовольствие перед TextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}


переопределить fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}


переопределить удовольствие afterTextChanged(s: Editable) {


элемент = BrokerField.text.toString()


fields.put("Имя", элемент!!)


val restRequest = RestRequest.getRequestForUpdate(ApiVersionStrings.getVersionNumber(контекст), "Broker__c", brokerId,


поля как Map?


клиент?.sendAsync (restRequest, объект: RestClient.AsyncRequestCallback {


переопределить удовольствие при успехе (запрос: RestRequest, результат: RestResponse) {}


переопределить удовольствие при ошибке (исключение: исключение) {}


вернуть rowView


В экосистеме Android адаптер определяет функциональность элемента пользовательского интерфейса. Здесь мы создали новый адаптер, который переопределяет определенное поведение ArrayAdapter. Мы добавили функцию под названием setClient, которая повторно использует тот же самый клиент Salesforce API, который нам нужен для заполнения списка в MainActivity. Функция «карта» связывает имя брокера с его пользовательским идентификатором объекта — причина, по которой это происходит, скоро станет очевидной.


getView — это место, где происходит основная часть активности. Самая важная строка связана с RestRequest.getRequestForUpdate. Клиент вызывает это для обновления данных Salesforce; для этого требуется имя пользовательского объекта, его идентификатор и значение для замены (в данном случае имя). Это событие происходит, когда срабатывает afterTextChanged; то есть после того, как пользователь завершил обновление имени брокера. В реальной производственной среде вам необходимо проверить коды состояния для потенциальных ошибок из API, но для краткости мы опустили какие-либо проверки ответов.


В MainActivity нам нужно использовать этот адаптер. Во-первых, в верхней части определения класса измените listAdapter на BrokerListAdapter вместо ArrayAdapter, например:


класс MainActivity : SalesforceActivity() {


частный клиент var: RestClient? = ноль


частный var listAdapter: ArrayAdapter? = ноль


частный lateinit var listAdapter: BrokerListAdapter


Модификатор lateinit позволяет вам инициализировать ненулевой тип вне конструктора. Затем замените две функции onResume на эти:


переопределить удовольствие onResume() {


// Скрыть все, пока мы не авторизуемся


mainViewBinding.root.visibility = Вид.НЕВИДИМЫЙ


// Создаем адаптер списка


listAdapter = BrokerListAdapter(этот)


mainViewBinding.brokersList.adapter = listAdapter


супер.onResume()


переопределить удовольствие onResume (клиент: RestClient) {


// Сохраняем ссылку на оставшийся клиент


this.client = клиент


listAdapter.setClient(клиент)


// Показать все


mainViewBinding.root.visibility = View.VISIBLE


sendRequest("ВЫБЕРИТЕ имя, идентификатор ОТ Broker__c")


Наконец, нам нужно отслеживать настоящее имя брокера вместе с его идентификатором записи. Для этого мы можем просто сохранить его в словаре, поддерживаемом BrokerListAdapter. В sendRequest замените цикл for на этот:


для (i в 0..records.length() - 1) {


listAdapter.add(records.getJSONObject(i).getString("Имя"))


listAdapter.map(records.getJSONObject(i).getString("Имя"), records.getJSONObject(i).getString("Id"))


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


Добавление данных


Мы можем редактировать записи, но что, если нам нужно добавить нового брокера? Формат для этого очень похож на логику, которую мы использовали для выборки и редактирования записей. Давайте быстро пройдемся по шагам.


Откройте main.xml и вставьте эти строки прямо перед ListView:


<LinearLayout андроид: ориентация = "горизонтальный"


Android: layout_width = "match_parent"


android:layout_height="wrap_content"


андроид: фон = "? андроид: цветной фон"


андроид: layout_marginStart = "10dp"


android:layout_marginEnd="10dp"


андроид: layout_marginTop = "10dp"


андроид: layout_marginBottom="10dp">


<Кнопка


android:id="@+id/add_broker"


Android: layout_width = "0dp"


андроид: layout_height = "47dp"


Android: onClick="onAddBrokerClick"


android:text="Добавить брокера"


Android: фон = "? android: colorPrimary"


android:textColor="?attr/sfColorSecondary"


андроид: layout_gravity = "центр"


андроид: layout_weight = "1"


android:layout_marginEnd="10dp"/>



Здесь мы добавили кнопку, которая будет вызывать функцию onAddBrokerClick при каждом ее нажатии. В MainActivity мы определим этот метод:


весело onAddBrokerClick(v: View) {


listAdapter.add("Новый брокер")


var fields: Map = mapOf("name" to "New Broker",


"Title__c" на "Младший брокер",


"Телефон__c" на "555-555-1234",


"Mobile_Phone__c" на "555-555-1234",


"Электронная почта__c" на "todo@salesforce.com",


«Picture__c» на «https://cdn.iconscout.com/icon/free/png-256/salesforce-282298.png»)


val restRequest = RestRequest.getRequestForUpsert(ApiVersionStrings.getVersionNumber(this), "Broker__c", "Id", null, поля)


клиент?.sendAsync (restRequest, объект: AsyncRequestCallback {


переопределить удовольствие при успехе (запрос: RestRequest, результат: RestResponse) {}


переопределить удовольствие при ошибке (исключение: исключение) {}


Да это оно! Те поля, которые мы определили, относятся непосредственно к пользовательскому объекту. Установив для Id значение null, мы сообщаем API, что это новая запись. Если вы добавите новую строку, отредактируете ее, а затем вернетесь в свою временную организацию, вы увидите, что новые данные появятся в сети.


Продолжение следует…


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


Однако это только одностороннее изменение данных — из приложения в организацию. Как насчет отправки данных из организации в приложение? Кроме того, как мы можем решить сетевые проблемы, характерные только для мобильных телефонов, такие как проблемы с подключением или одновременное изменение полей несколькими людьми? Мы рассмотрим эти очень реальные проблемы в нашем заключительном посте!


  • Впервые опубликовано [здесь] (https://dev.to/mbogan/building-a-kotlin-mobile-app-with-the-salesforce-sdk-editing-and-creating-data-1pb6)*


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