Как сделать так чтобы на почту не приходили письма с разных сайтов на айфоне

Обновлено: 06.07.2024

Со стороны пользователя почтовый клиент — приложение нехитрое. Разработчики Яндекс.Почты даже шутят, что в приложении всего три экрана: список писем; отправка письма; экран about.

Но очень много интересного происходит под капотом. Как многие мобильные приложения, Почта использует push-уведомления, чтобы взаимодействовать с пользователями. Как многие iOS-приложения, Почта теряет часть уведомлений в силу особенностей работы Apple Push Notification Service.

Руководитель iOS-группы Яндекс.Почты Ася Свириденко докажет, что даже с учетом ограничений системы, с потерями push-уведомлений можно и нужно бороться, если они критичны для вашего приложения. Для Почты это так, потому что push-уведомления о новых письмах — это то, ради чего пользователь устанавливает приложение. Если же для вашего приложения доставка push-уведомлений не так критична, узнать, какие велосипеды нагородила мобильная Яндекс.Почта, все равно интересно.

Речь пойдет о remote notification, то есть уведомлениях, которые приходят с сервера через APNs (Apple Push Notification Service). Локальные уведомления затрагивать не будем и поговорим о том:

  • Как выглядит API для работы с push-уведомлениями. Рассмотрим схему доставки push-уведомлений и то, где в этой схеме могут возникать потери.
  • Как решили бороться с потерями в Яндекс.Почте — об очереди push-уведомлений.
  • Как логировать и какие еще сложности могут встретиться.

Что имеем и где теряем

Сейчас API для работы с push-уведомлениями — это достаточно мощная штука, которая позволяет делать много интересных вещей. Но так было не всегда.


Раньше push-уведомления выглядели именно так — это была несчастная голубая плашка, которая всплывала на экране, блокировала работу с текущим приложением, не давала ничего сделать, а потом пропадала навсегда, и больше никаких напоминаний о ней не было.

С тех пор прошло достаточно времени.


Для нас, как для разработчиков, все началось в iOS 3, когда push-уведомления стали доступны для сторонних библиотек.

В iOS 5 появился Notification Center, и push-уведомления перестали уходить в никуда, теперь они остаются в Notification Center, где их можно посмотреть повторно.

Эти изменения касались в основном того, как пользователь может работать с push-уведомлениями, как они могут сделать его жизнь комфортнее, а не того, как разработчики могут влиять на уведомления.

Для разработчиков важной вехой стал iOS 8 и появление Notification Action, которые позволили выполнять по push-уведомлениям действия, характерные для конкретного приложения.

В iOS 10 появились Notification Service Extension и Notification Content Extension. Первый позволяет модифицировать push-уведомление до того, как оно будет показано пользователю. Второй — по Force Touch на push-уведомление показывать некоторый UI, в котором, например, можно отображать более детальную информацию. В iOS 10 этот UI был некликабельный — смотреть можно, трогать нельзя.

В iOS 11 появился Notification Privacy Settings. Теперь пользователь может зайти в настройки и указать, хочет ли он, чтобы в пришедших уведомлений отображалось содержимое. Это огромный шаг в сторону безопасности. Понадобилось всего 8 версий iOS, чтобы понять, что не все пользователи хотят, чтобы на лежащем на столе iPhone внезапно всплывала персональная информация.

В iOS 12 появилась возможность группировать push-уведомления по thread-id, и тот UI, который мы получили в iOS 10 с помощью Notification Content Extension, стал кликабельным. Теперь туда можно добавлять кнопки и управление жестами — все то, что помогает пользователю взаимодействовать с UI.

Push-уведомления сегодня

Как вы видите, push-уведомления прошли огромный путь, и сегодня с их помощью можно делать действительно много всего.

Звук и critical alert

Как и раньше, можно добавлять звуки в payload уведомления.

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

Silent-уведомления


Для того, чтобы push-уведомление стало silent, необходимо в payload указать: "content-available" : 1 . И не указывать alert, sound и badge ключи в payload — они совершенно бесполезны для push-уведомления, которое не будет показано пользователю.

Группировка уведомлений


Это очень удобно, потому что теперь push-уведомления не занимают все место на заблокированном экране, а сгруппированы вместе. Если вы еще не используете эту функциональность, самое время начать.

Изменение уведомления до его показа

Push-уведомления можно менять до того, как они будут показаны. Для этого необходимо добавить в приложение Notification Content Extension и переопределить метод didReceive . В этом методе можно получить контент уведомления и модифицировать его.

Еще интересный кейс — можно отправлять push-уведомление с зашифрованным контекстом, если хотите, чтобы данные были дополнительно защищены, и Apple их не увидел. В Notification Content Extension вы сможете их дешифровать и показать пользователю уже дешифрованные данные.

Скрытый контент уведомления

Действия по уведомлению без запуска приложения

Чтобы осуществлять действия по push-уведомлению без запуска самого приложения, необходимо создать категорию и добавить в нее action. Identifier категории передается в поле category у payload уведомления. Можно подключать разные actions к разным типам уведомлений.

Rich Notifications

В этом расширении можно обрабатывать дополнительные действия, которые вы добавили к push-уведомлению, и показывать custom UI.

Для этого необходимо в приложение добавить Notification Content Extension, определить в нем класс, который наследуется от UNNotificationContentExtension, и дальше работать с ним, как с обычным UIViewController.


Если вы обрабатываете кастомные действия, важно помнить, что по этим действиям стоит обновить UI, который вы показываете пользователю. Не надо пытаться реализовать в этом расширении бизнес-логику. Отправлять запрос на сервер по действию с push-уведомлением надо в основном приложении, а не здесь. Это место только для UI.

Схема доставки push-уведомлений

Видите, сколько всего можно сделать с push-уведомлениями в iOS. От версии к версии у нас появляется все новая и новая функциональность, но схема доставки push уведомлений сейчас точно такая же, какая она была в iOS 3.


Можно было бы подумать, что схема доставки push-уведомлений была прекрасна с самого начала, но это не так.

В схеме доставки push-уведомлений есть три основных узла:

  • провайдер, который формирует payload push-уведомления;
  • APNs — Apple Push Notification Service, который доставляет уведомление;
  • устройство с iOS и вашим приложением.

В Яндексе провайдер, формирующий payload, называется XIVA. XIVA — это база данных подписок. Почта использует XIVA для работы с push-уведомлениями как стороннюю библиотеку.

Где потери?

В схеме доставки push-уведомлений четыре стрелочки, потери могут возникать на трех из этих переходов.

Между XIVA и APNs могут возникать потери, связанные с сетью. Мы почти не можем повлиять на сеть, поэтому останавливаться на этом пункте не будем.

Это те самые потери, которые не позволяют нам гарантировать доставку и полагаться на push-уведомления. Apple явно пишет, что доставка не гарантирована.

Между Extension приложения и iOS потерь возникать не может, и Apple это гарантирует. Если вы используете Extension и переопределили метод didReceiveContent with completion, даже если вы не вызовете этот completion, уведомление будет показано все равно. Об этом важно помнить. Вы можете его не вызвать или не успеть его вызвать, но тогда уведомление будет показано без каких-либо изменений, в том виде, в котором оно приходит из APNs.

Мы рассмотрим, как мы бороться с потерями между APNs и Extension. Но если вам понадобится увеличить доставляемость push-уведомлений, посмотрите на всю схему. Проверьте, не возникают ли потери на стороне сервиса, нормально ли ваш провайдер взаимодействует с APNs и так далее. Проверьте и измерьте всю цепочку, а потом уже делайте выводы, где больше всего возникает потерь и какую часть этой схемы стоит модифицировать.

Очередь push-уведомлений

Наш способ борьбы с потерями в связке APNs и Extension мы назвали очередью push-уведомлений.

Если сжать весь рассказ до одной фразы, то это будет:


В нашей схеме доставки уведомлений все те же самые участники: XIVA, APNs, Extension. Упрощенно схема работает так:

Чтобы уведомления не дублировались, мы используем apns-collapse-id. Эта настройка позволяет на стороне iOS схлопывать push-уведомления с одинаковыми ID. Если на устройство пришло несколько push-уведомлений с одинаковым apns-collapse-id, iOS их схлопнет, и пользователь увидит только одно уведомление.

Расскажу, как это все работает на XIVA, потому что всегда любопытно, что происходит на бэкенде.

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

  • В качестве ключа выступал .
  • В качестве value хранился payload (данные о письмах в случае Почты).

Для сквозной нумерации push-уведомления должны были пронумерованы по устройству и app_name. То есть сквозная нумерация нужна для конкретного устройства и для конкретного приложения, чтобы опираться на неё на стороне клиента. Сделали это следующим образом: переиспользовали базу данных XIVA, но стали записывать в неё payloads по другому ключу. Теперь в качестве сервиса выступает apns_queue, в качестве юзера device_id + app_name — те самые данные, по которым нужна нумерация на клиенте, то есть key: .

На клиенте используется Notification Service Extension.


В нем переопределяем метод didReceive и смотрим, что же пришло с сервера. Всем push-уведомлениям добавляем "mutable-content" : 1 , чтобы они попали в Extension, потому что иначе не можем учесть их в расчетах.


Логируем, проверяем, не поменялся ли deviceId, так как знаем, что в iOS это возможно. Честно говоря, мы с изменением deviceId так и не столкнулись, но на всякий случай обрабатываем, потому что если он изменится, мы не сможем доверять нумерации от XIVA.


Дальше смотрим, можем ли получить данные XIVA в этом payload, есть они или нет. Если нет, снова вызываем contentHandler.


Если данные есть, проверяем, для того ли deviceId пришли данные. XIVA присылает в payload хэш устройства, если сверили и совпало, продолжаем, нет — вызываем contentHandler.


Следующим блоком смотрим, есть ли сохраненная позиция:

  • Если у нас нет последней сохраненной позиции, то мы либо еще не получали уведомления и не заходили в Extension, либо по какой-то причине дропнули. Тогда не от чего отталкиваться, чтобы посчитать diff пропущенных, и мы снова вызываем completion.
  • Если есть, идем дальше.

Считаем количество пропущенных уведомлений. Если пропущенных ноль — отлично, мы ничего не пропустили.


Иначе берем из XIVA данные по позиции — из той самой сквозной нумерации. Дальше смотрим, не превышает ли количество пропущенных некое заданное значение.

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

Логирование и прочие сложности

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

Ограничения push-extension

Первое, с чем мы столкнулись, — это ограничения push-extension.

Не всегда вызывается. Если в настройках приложения выключить отрисовку уведомлений (возможность получать уведомление остается включенной, но выключаются все возможные отрисовки), Extension вызван не будет — не будет вызвана вся логика с пересчетами и, самое главное, логирование. Мы не сможем узнать то, что нам важнее всего, — получил ли пользователь уведомление.

У push-extension есть ограничение по времени. В документации Apple написано, что в течение примерно 30 секунд необходимо вызвать completion с видоизмененным уведомлением, иначе будет показано изначальное уведомление.

Мы стали смотреть, в чем разница между этими push-уведомлениями, и выяснили, что разницы нет, просто для одних мы успеваем вызвать completion, а для других нет. Соответственно, когда не успеваем, push-уведомления показывается именно в том виде, в котором пришли с APNs.

Третье ограничение — по памяти. Apple предупреждает, что память, выделяемая на push-extension, ограничена, и не рекомендует загружать в него тяжелые данные, но не уточняет точный размер. У нас получилось, что это примерно 12 МБ.

На Apple Developer Forum разработчики активно обсуждают, какие есть ограничения, высказывают свои предположения и пытаются их точно вычислить. Ограничения на память немного отличаются, но порядок примерно такой — 10 МБ.

Мы столкнулись с этим ограничением, когда добавляли логирование. Для логирования мы используем Яндекс AppMetrica. Когда мы начинали, AppMetrica для загрузки требовалось много памяти, и наш Extension все время отваливался. Поэтому нам пришлось нагородить маленький велосипед, чтобы все-таки залогировать получение уведомлений.

Измерение результатов превратилось в игру: попытку не уронить Extension и залогировать данные.

Измеряем результаты

В итоге логирования push-extension пишет данные в UserDefaults. Потом, когда основное приложение просыпается, оно отправляет данные в AppMetrica.

У этого подхода есть минусы. Основной из них сказывается на измерении. Нам пришлось учитывать, что пользователи не обязательно запускают приложение в тот же день, это вообще может произойти через месяц. Поэтому мы строим выводы только на основе измерений тех пользователей, которые запустили приложение в тот же или на следующий день. Иначе у нас будет большое несоответствие между теми данными, которые отправила XIVA (мы их логируем), и тем, что получил пользователь.

Важно помнить, что Notification Extension работает с iOS 10 и выше, поэтому если вы логируете данные через Extension, не забывайте удалять данные о тех пользователях, которые используют более ранние версии.

В защиту AppMetrica: очень многое сделано с тех пор, push-extension уже давно не падает по памяти. В AppMetrica есть логирование push-уведомлений, и я думаю, что в ближайшее время мы выкинем наш велосипед и вернёмся к нормальному логированию. Какие есть возможность, можно прочитать в AppMetrica Push SDK.

Вот, что показали измерения. график за январь — было до того, как внедрили очередь. По вертикали доставляемость, по горизонтали время.


Явные падения — это выходные дни, когда пользователи и меньше отправляют уведомлений, и гораздо реже открывают почту.

После того, как мы внедрили очередь push-уведомлений, характер графика сохранился, но при этом доставляемость стала гораздо выше — график за февраль.

Доставляемость увеличивается, а значит, мы движемся в верном направлении. Тут можно было бы и остановиться, но…

Фрустрация

Мы сделали многое: написали код, посчитали, графики нарисовали. Но как определить, сработало ли? Изменилось ли что-то от того, что мы внедрили очередь push-уведомлений? Доставляемость увеличилась, а как это повлияло на работу с приложением? Как это поменяло user experience и сценарий работы?

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

Итоги

Push-уведомления в iOS прошли большой путь. Если вы еще не используете их в своем приложении или используете по минимуму, посмотрите на пример Яндекс.Почты. Возможно, некоторые решения вам пригодятся.

Пропущенные push-уведомления можно (и нужно) перезапрашивать. Совершенно необязательно делать это как в Яндекс.Почте через XIVA. Может, у вас есть похожий сервис, который поможет вам в этом. Может, найдете сторонний, который тоже умеет делать нечто подобное. Ищите!

Помните про ограничения push-extension. Не перегружайте его по памяти, учитывайте ограничение по времени. Следите, чтобы он вызывался.

Подумайте, что вам даст улучшение доставки. Прежде, чем ввязаться в эту авантюру, подумайте, нужно ли вам это, даст ли это что-то вашему приложению. Возможно, увеличение доставляемости push-уведомлений для вашего приложения абсолютно не критично и ничего вам не даст. Но, возможно, именно вам оно даст прирост пользователей, и вы окажетесь на вершине App Store, где мы все хотим оказаться, и обязательно окажемся!

Мы в AppsConf с нетерпением ждем следующего доклада Аси, в котором она уже 21 или 22 октября расскажет об идеях и открытиях, родившихся за время рефакторинга большей части приложения Яндекс.Почты. В равной степени мы предвкушаем еще почти 50 выступлений, призванных помочь мобильным разработчикам расти. До 1 сентября можно подать заявку на доклад и оказаться в компании крутых людей, которые прямо влияют на будущее индустрии — успевайте.

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

WWDC-2019-Craig-Federighi-Safari-Mail-Notes-slide-001

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

Как отключать уведомления в Почте

1) Откройте приложение Почта на своём iPhone или iPad с iOS 13 и новее.

2) Найдите переписку, уведомления из которой хотите отключить.

3) Проведите по переписке влево, чтобы открыть меню с опциями, и выберите Ещё.

4) Теперь выберите Не уведомлять.

1

Теперь вы не будете получать уведомления о новых письмах из этой переписки на всех своих устройствах. Рядом с перепиской появится значок с перечёркнутым колокольчиком. Это значит, что уведомления отключены.

Как включать уведомления в Почте

1) Откройте приложение Почта на своём iPhone или iPad с iOS 13 и новее.

2) Найдите переписку с отключенными уведомлениями (рядом с ней будет перечёркнутый колокольчик).

3) Проведите по переписке влево и выберите Ещё.

4) Теперь нажмите Уведомлять.

1

Уведомления из переписки будут включены на всех ваших устройствах.

Как настроить, куда деваются письма?

По умолчанию новые письма из таких переписок автоматически отмечаются как прочитанные. Это можно изменить.

1) Откройте приложение Настройки на своём iPhone или iPad с iOS 13 и новее.

2) В основном списке выберите секцию Почта.

3) Выберите пункт Для тем без звука.

4) Теперь выберите одно из предложенных действий:

  • Как прочитанное: Новые письма будут автоматически отмечаться как прочитанные.
  • В архив или удалить: Новые письма будут архивироваться или удаляться.

index

Архивирование или удаление?

index

Данная опция также определяет, куда отправляются удалённые вручную письма.

Более быстрый способ управлять уведомлениями

Как отказаться от рассылки писем на Gmail?

Как отказаться от рассылки

Как сделать чтобы на почту не приходили ненужные письма на айфоне?

Чтобы рекомендации о том, от каких рассылок вам можно отказаться, не появлялись:

Как не получать спам на почту майл?

Как избавиться от спама на андроид?

Вот как это делается в Chrome:

Как отписаться от рассылки на почту Gmail с телефона?

Как отказаться от рассылки

Как посмотреть рассылки на почту?

Посмотреть письма рассылки

Как отписаться от рассылки в телефоне?

Также можно отписаться от push-уведомлений в настройках сайта.

Как отменить подписку на рассылку в Gmail?

Как отменить подписку на Google Workspace

Как сделать так чтобы письма не попадали в спам Gmail?

Как заблокировать почту от конкретного отправителя на айфон?

Как заблокировать e-mail конкретного отправителя (внести в черный список) в приложении Почта на iPhone, iPad или Mac

  1. Откройте необходимое письмо и коснитесь имени отправителя.
  2. Повторно коснитесь имени отправителя.
  3. В открывшейся карточке контакта дважды нажмите Заблокировать контакт.

Как удалить подписки в iCloud?

Как заблокировать почту от конкретного отправителя?

Если заблокировать отправителя, все письма от него будут помещаться в спам.

Как заблокировать почту от конкретного отправителя на айфон?

Как заблокировать e-mail конкретного отправителя (внести в черный список) в приложении Почта на iPhone, iPad или Mac

  1. Откройте необходимое письмо и коснитесь имени отправителя.
  2. Повторно коснитесь имени отправителя.
  3. В открывшейся карточке контакта дважды нажмите Заблокировать контакт.

Как отписаться от всех рассылок iCloud?

Как сделать так чтобы на почту не приходили ненужные письма?

Как в mail добавить адрес в черный список?

Как отписаться от рассылки на почту Gmail с телефона?

Как отказаться от рассылки

Как заблокировать рассылку на почту на айфоне?

Как отписаться от почтовой рассылки (спама) в Почте на iPhone и iPad

Что будет если добавить номер телефона в черный список?

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

Как найти черный список в айфоне?

Чтобы отключить службу iMessage, выполните приведенные ниже действия.

Как отписаться от рассылки на электронную почту?

Как отписаться от рассылки смс?

Читайте также: