Как создать компоненты почтового ящика и списка сообщений для приложений iOS

Эффективно общайтесь со своими пользователями с помощью почтового ящика в приложении

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

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

  • Пользователи, запрашивающие оценки во время использования приложения. Несмотря на то, что рекомендуется запрашивать оценку после положительного опыта работы с приложением (например, прохождения уровня в игре), это не всегда эффективно, особенно в образовательных приложениях, где вы не хотите мешать изучению пользователя. поток.
  • Распространение спама в электронных письмах или уведомлениях. Концепция нулевого почтового ящика (идея о том, что в вашем почтовом ящике не должно быть ни одного или почти полного отсутствия электронной почты) родилась из-за большого количества нежелательной, старой или нерелевантной электронной почты, которую получают люди. . Наличие чистого и организованного почтового ящика повышает продуктивность и снижает беспокойство, и нужно строго следить за тем, какие информационные бюллетени, уведомления и т. Д. Разрешены в их почтовом ящике. Разработчики приложений должны знать об этой концепции и должны экономно отправлять электронные письма пользователям - и на самом деле существуют стратегии для этого.
  • Неэффективное использование внешних служб. В идеале пользователи не хотят прыгать между приложениями (или, что еще хуже, браузером), чтобы иметь дело с сообщениями, связанными с приложением. Электронная почта является хорошим примером этого, а также инструменты управления командой, такие как Slack, которые действуют как заменители каналов доставки сообщений.

Решение, которое позволяет обойти эти проблемы, - это почтовый ящик в приложении, который подводит нас к цели этой статьи. В частности, эта часть будет охватывать ключевые компоненты (которые кратко описаны в следующем разделе) для создания собственного почтового ящика в приложении React Native. Это дает ряд преимуществ, которые нравятся как разработчику, так и пользователю:

  • Больше возможностей повторного использования. Возвращение пользователя обратно в ваше приложение, где он с большей вероятностью проведет еще один сеанс, в отличие от обращения к нему из внешней службы.
  • Меньше полагаться на третьи стороны. Снижение вашей зависимости от сторонних поставщиков услуг электронной почты, таких как Send Grid или Mailgun, которые применяют многоуровневую модель и, следовательно, устанавливают ограничения на количество отправляемых электронных писем. (если вы не заплатите больше).
  • Минимум уведомлений. Возможность более эффективного управления уведомлениями. Например. если вы отправляете пользователю 5 отдельных сообщений, вы можете доставить одно уведомление, уведомляющее пользователя о наличии нескольких сообщений.
  • Упрощенная навигация. Возможность ссылаться на другие области вашего приложения только с помощью React Navigation, не беспокоясь о механизмах Deep Linking.
  • Настройка. Возможность настраивать внешний вид своего почтового ящика в соответствии с тематикой вашего приложения, а также иметь разные типы сообщений, которые влекут за собой разный UX. Доставка в приложении на порядок более гибкая, чем предложения сторонних сервисов.

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

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

В следующем разделе мы разберем ключевые компоненты, использованные для создания этого почтового ящика. В этой части мы более подробно коснемся 3 ключевых компонентов и того, как их настраивать.

Ключевые компоненты почтового ящика

В этой статье конкретно обсуждаются 3 основных компонента этой функции почтового ящика:

  • Настройка Navigator для выполнения этой работы, включая модальный стиль iOS, который придает плавный вид модальному ящику входящих сообщений.
  • Как настроить Список сообщений с помощью FlatList, переключаться между вкладками (вкладка "Входящие" и "Архив"), а также открывать для обновления. Мы также задокументируем методы, позволяющие предварительно перевести входящие сообщения в состояние, прежде чем пользователь откроет их. Скрытие папки «Входящие» по умолчанию дает приложениям возможность синхронизировать папку «Входящие», готовые отображать самое актуальное состояние сообщения.
  • Каждый элемент списка сообщений в списке входящих представляет собой сообщение, которое пользователь может нажать для просмотра. Компонент ScrollView используется для включения смахивания, чтобы открыть кнопку архива, и в этом заключается сложность. В этой статье будет рассказано, как добиться этого эффекта, и отсылаться к моей статье о представлениях с горизонтальной прокруткой и карусели, в которой более подробно рассказывается о том, как настроить компонент.

Настройка навигатора входящих сообщений

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

Для этого навигатор стека в ваш почтовый ящик должен быть встроен в родительский навигатор стека режима modal. Вот эта установка:

// structure of your navigators
Navigation Container
   Main Stack Navigator
     Dashboard Screen
        Dashboard Navigator
      Inbox Screen
        Inbox Stack Navigator
           Message List
           Message

Если читатель еще не знаком с React Navigation, ознакомьтесь с моей вводной статьей о React Navigation 5: Начните с React Navigation 5 в React Native.

Это обычная настройка, при которой Main Stack Navigator удерживает экраны каждого раздела вашего приложения в различных суб-навигаторах. Важно, чтобы Inbox Screen был частью этого родительского навигатора, чтобы успешно наложить текущий активный контент (в приведенном выше случае это будет экран панели инструментов). Ниже приведен полный пример кода, чтобы продемонстрировать эту структуру.

Обратите также внимание на то, что основное содержимое откатывается по мере того, как ящик Входящие скользит вверх, и что в папке Входящие остается небольшой зазор в верхней части экрана, помимо закругленных краев. Этот эффект перехода фактически встроен в React Navigation в параметре конфигурации cardStyleInterpolator, для которого требуется значение CardStyleInterpolators.forModalPresentationIOS.

Это CardStyleInterpolators.forModalPresentationIOS модальное представление было введено в iOS13. Принятие этого стиля сделает ваши приложения более родными для iOS.

Следующая суть описывает, как именно настроить такую ​​установку:

Я сделал несколько заметок в самой сути, но есть несколько интересных моментов, которые стоит проверить при настройке собственного:

  • Не забудьте включить значение CardStyleInterpolators.forModalPresentationIOS в параметр cardStyleInterpolator для экранов, которые должны отображаться как модальные окна iOS13.
  • Свойство gestureEnabled: true в опоре options экрана Message гарантирует, что пользователь может провести по горизонтали, чтобы вернуться к основному Messages списку.

Теперь, когда навигатор настроен, вы можете подключить компоненты Messages и Message для отображения списка сообщений и самого содержимого сообщения. В следующих разделах подробно описывается, как именно они настраиваются. Пока мы говорим о навигаторах, вот некоторые дополнительные конфигурации, которые следует учитывать:

  • Чтобы закрыть модальное окно с помощью кнопки, просто вызовите navigation.goBack() для события onPress кнопки. Возможность смахивать вниз от верхней части модального окна встроена в навигатор.
  • При посещении экрана сообщений для отображения содержимого сообщения компонент Message должен знать, какое сообщение отображать, относительно того, какой элемент вы коснулись в списке сообщений. Params можно использовать в таком случае, когда весь элемент сообщения может быть отправлен в Message как параметр в форме объекта JSON:
// sending a message object to `Message` component via params
onPress={() => navigation.navigate('Message', {
  item: item, // `item` represents the entire message object
  ...
})}>

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

Отображение списка сообщений

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

Использование FlatList для отображения сообщений

Компонент FlatList на сегодняшний день является лучшим компонентом для вывода списка сообщений по следующим основным причинам:

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

Эта структура идеально подходит для отображения папки «Входящие». Вот визуальное представление структуры FlatList с соответствующей опорой для каждого элемента:

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

То, что кажется довольно аккуратным и читаемым кодом, на самом деле имеет много функциональных возможностей. В частности:

  • Свойства ListHeaderComponent и FooterHeaderComponent позволяют нам встраивать JSX непосредственно в пространства верхнего и нижнего колонтитула до и после FlatList элементов соответственно. Эта поддержка позволяет самому FlatList занимать всю высоту экрана, при этом не требуется дополнительного места для поддержки внешних компонентов заголовка (если вы не разрабатываете липкий заголовок).
  • data представляет фактические данные сообщения, которые будут массивом объектов JSON, представляющих содержимое сообщения. Свойство keyExtractor использует поле _id каждого элемента для присвоения каждому из них уникального ключа.
  • обратите внимание, что компонент <RefreshControl /> внутри опоры refreshControl предоставляется react-native. Обратите внимание, что refreshMessages() должен быть определен в том же компоненте, что и FlatList, с задачей связаться с вашим сервером для получения списка последних сообщений.
  • Внутри renderItem есть два компонента, которые могут отображаться в зависимости от поля item.template. Это демонстрирует гибкость отображения различных стилей элементов сообщения в зависимости от ваших потребностей. Еще раз просмотрите демонстрационный экран и обратите внимание на сообщение «Оценить и просмотреть» внутри архива входящих сообщений - этот элемент использует другой шаблон, чем сообщения по умолчанию. Это всего лишь один пример того, как вы можете настроить свой почтовый ящик.

Предварительное заполнение вашего почтового ящика с помощью Redux

Хранение сообщений в глобальном состоянии, например в хранилище Redux, является эффективным средством управления вашими почтовыми ящиками. Такие задачи, как отметка сообщения как прочитанного, а также архивирование или удаление сообщений, можно просто выполнить, отправив действия Redux.

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

Эта процедура «синхронизации» (чаще всего это запрос на извлечение сообщений из почтового ящика) может выполняться в различных местах вашего приложения, например:

  • Когда пользователь открывает приложение на переднем плане, приложение может синхронизироваться с помощью обратного вызова события AppState.
  • Когда пользователь посещает экран в вашем приложении, например панель мониторинга. Запуск синхронизации на часто посещаемом экране заставляет приложение оставаться в актуальном состоянии.

Вот как этот процесс может выглядеть с AppState:

Теперь, когда пользователь посещает свой почтовый ящик, истинное состояние сообщения будет отображаться без дальнейшей выборки.

Чтобы узнать больше о Redux и, в частности, об использовании Redux-хуков, ознакомьтесь с моей статьей на эту тему: Redux-хуки в React: Введение.

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

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

Переключение между почтовыми ящиками

Демонстрационный скринкаст этой статьи продемонстрировал два списка сообщений; список «Входящие» и «Архив». Функциональность перемещения сообщений между почтовыми ящиками является одной из важных, поэтому пользователь может сохранять интересующие сообщения в основном почтовом ящике и удалять другие во вторичный.

Структура данных, которой необходимо придерживаться в вашем хранилище Redux, не слишком сильно меняется, чтобы поддерживать это. Одна структура, которая будет работать, будет следующей:

// JSON structure of multiple inboxes 
messages: {
  inbox: [
   {
     _id: 1,
     title: 'Welcome!',
      ...
   }, {
     _id: 2,
     title: 'How to Use This App',
     ...
   },
  ],
  archive: [
   {
     _id: 3,
     title: 'Not so interesting message.',
      ...
   }
  ]
};

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

Чтобы переключаться между почтовыми ящиками, какое-то простое локальное состояние может определять, какой почтовый ящик отображается:

// `activeInbox` local component state to control which inbox is displayed
const [activeInbox, setActiveInbox] = useState('inbox');
const data = activeInbox === `inbox`
   ? props.messages.inbox
   : props.messages.archive;
...

Обратите внимание, что хранилище Redux также может управлять состоянием на основе пользовательского интерфейса, например activeInbox, и может быть более полезным, если вы хотите сохранить папку входящих сообщений, которую пользователь посещал последним.

В заключительном разделе этой части мы рассмотрим сам компонент сообщения, который отображает каждое сообщение в списке входящих.

Компонент прокрутки элемента сообщения

Это, пожалуй, самый сложный компонент почтового ящика, поскольку он представляет собой горизонтальный ScrollView компонент в сочетании с несколькими TouchableOpacity компонентами для обработки взаимодействий. В следующем примере есть две активные сенсорные области:

  • Отображение заголовка / аватара сообщения - это кнопка, при нажатии которой осуществляется переход к содержимому сообщения.
  • Текст «Архивировать / Разархивировать», который пользователь должен смахнуть влево, чтобы отобразить, чтобы переместить сообщение между почтовыми ящиками.

С учетом сказанного, давайте посмотрим, как устроен этот компонент:

Чтобы узнать о других способах использования представлений с горизонтальной прокруткой и различных конфигурациях с помощью варианта использования карусели, ознакомьтесь с моей специальной статьей о них: React Native: карусели с представлениями с горизонтальной прокруткой.

В этом ScrollView есть два элемента. Главный элемент, отображаемый по умолчанию, занимает 100% ширину содержащего его компонента (равного FlatList). Этот элемент отображает основное содержимое этого компонента - заголовок, аватар и метаданные сообщения. Второй элемент - это кнопка «архивировать / разархивировать», которая занимает дополнительную 30% ширину.

Чтобы понять, как это работает, давайте посмотрим, как это выглядит в таблице стилей.

Настройка таблицы стилей

Следующий псевдокод отражает компоненты и примененные стили для достижения горизонтальной прокрутки со скрытой кнопкой:

// structure of the message list with style names
<View style={styles.container}>
   <ScrollView style={styles.scrollview}>
      
      <TouchableOpacity style={styles.item}>
         {/* display message preview */}
      </TouchableOpacity>
      
      <TouchableOpacity style={styles.archive}>
         {/* display archive text*/}
      </TouchableOpacity>
   </ScrollView>
</View>

Самый внешний <View /> компонент просто ограничивает максимальную видимую ширину до 100% и скрывает перекрывающееся содержимое:

container: {
  width: '100%',
  overflow: 'hidden',
}

Компонент <ScrollView /> установлен на фиксированное значение 130% с конфигурацией гибкой строки:

scrollview: {
  display: 'flex',
  flexDirection: 'row',
  width: '130%',
},

У нас есть два <TouchableOpacity /> компонента, которые занимают все пространство прокрутки. Первый завершает предварительный просмотр сообщения, занимая первые 100% пространства:

item: {
  flexBasis: '100%',
  maxWidth: '100%',
  paddingVertical: 5,
  paddingHorizontal: 20,
},

Обратите внимание, что здесь важно свойство maxWidth, чтобы ограничить ширину желаемым значением.

На втором <TouchableOpacity /> размещена кнопка Архивировать, которая использует централизованную гибкую конфигурацию для центрирования текста как по горизонтали, так и по вертикали:

archive: {
  flexBasis: '30%',
  maxWidth: '30%',
  display: 'flex',
  flexDirection: 'row',
  alignItems: 'center',
  alignContent: 'center',
  justifyContent: 'center',
},

Прокрутка просмотра реквизита

По умолчанию <ScrollView /> - это вертикальная прокрутка, и для нее не включено разбиение по страницам (привязка к определенным положениям прокрутки для обозначения разделов). Вот несколько основных параметров для настройки просмотра с горизонтальной прокруткой, которые будут включать разбиение по страницам на основе компонентов удержания <ScrollView /> (item и archive):

<ScrollView
  horizontal={true}
  contentContainerStyle={styles.scrollview}
  showsHorizontalScrollIndicator={false}
  scrollEventThrottle={200}
  pagingEnabled
  decelerationRate="fast">
    {/ * content */}
</ScrollView>

Обратите внимание, что реквизиты horizontal и pagingEnabled являются ключевыми здесь. Нам не нужны индикаторы прокрутки в списках сообщений, поэтому showsHorizontalScrollIndicator был установлен на false. Кроме того, decelerationRate из fast кажется намного более естественным при работе с представлениями с горизонтальной прокруткой, которые не занимают весь экран.

Я подробно рассказал о различных свойствах и параметрах конфигурации <ScrollView /> в моей статье, посвященной карусели: React Native: карусели с горизонтальной прокруткой.

Разное сообщение Примечания к предмету

Вот еще несколько небольших заметок, которые я посчитал примечательными при настройке элементов списка сообщений:

  • LayoutAnimation следует использовать для перехода между раскладками при изменении списка сообщений; Например. когда вы архивируете сообщение, оно удаляется из папки Входящие. LayoutAnimation автоматически обрабатывает этот переход и поддерживает ряд эффектов. Например, чтобы просто скрыть элемент, примените LayoutAnimation.configureNext до того, как произойдет обновление состояния:
// apply `LayoutAnimation` before state update
LayoutAnimation.configureNext(
  LayoutAnimation.create(
    300,
    LayoutAnimation.Types.easeInEaseOut,
    LayoutAnimation.Properties.opacity
  )
);
// state updates
setInbox(newInbox);

В этом примере применяется функция замедления с функцией непрозрачности и устанавливается продолжительность 300.

  • SVG Поддержка аватаров и иконок. Хотя мы могли бы погрузиться в целую статью о поддержке SVG в React Native, самый простой способ - установить react-native-svg-transformer в качестве зависимости разработчика и настроить файлы metro.config.js и app.js для поддержки формата файла SVG.
  • Чтобы отображать относительное время в ваших сообщениях, например, когда сообщение было отправлено или как давно оно было отправлено, обязательно используйте moment.

В сводке

В этой статье были исследованы 3 ключевых компонента для создания почтового ящика в React Native. Сначала мы исследовали сам навигатор, созданный с помощью React Navigation 5. Навигаторы стека сразу же поддерживают модальный стиль iOS 13, придавая вашему приложению естественный и плавный вид.

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

В последнем разделе документируется компонент элемента сообщения, в котором используется горизонтальная прокрутка для размещения как предварительного просмотра сообщения, так и скрытой кнопки «Архивировать». Для каждого компонента задокументированы определенные свойства таблицы стилей, а также необходимые <ScrollView /> реквизиты.

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

  • Индикатор непрочитанного сообщения (обычно это цветной кружок рядом с заголовком сообщения), сигнализирующий о том, что вы еще не открыли сообщение.
  • Сам экран сообщений - как бы вы стилизовали этот экран, чтобы он лучше всего подходил для вашего приложения?
  • Уведомления и значки, чтобы пользователи знали, что пришло новое сообщение. Узнайте больше о push-уведомлениях Apple для React Native и NodeJS здесь.

Дальнейшее чтение

Чтобы расширить это решение с помощью значков уведомлений, ознакомьтесь с моей последующей статьей о том, как интегрировать значки уведомлений в React Native, вызывая значки как локально в React Native, так и на стороне сервера с полезными нагрузками APN:



Если же вы, с другой стороны, хотите отказаться от ручной доставки сообщений пользователям, чтобы автоматически доставлять их массово, ознакомьтесь с моей статьей Node.js, в которой демонстрируется демонстрация того, как делать именно это с помощью службы времени выполнения: