Інтеграція електронної пошти в мобільний додаток
Відправити лист з мобільного додатка — завдання з кількома рівнями складності. Можна відкрити нативний поштовий клієнт через mailto: і назвати це інтеграцією. Можна відправляти трансакційні листи через SMTP прямо з пристрою, чого в продакшені ніхто не повинен робити. А можна правильно — через API поштового провайдера з сервера, але з зручним інтерфейсом у додатку.
Три сценарії та їхня реалізація
Сценарій 1: Відкриття нативного клієнта. Найпростіший. На iOS — MFMailComposeViewController з MessageUI.framework, на Android — Intent.ACTION_SENDTO з Uri.parse("mailto:"). Підходить коли потрібно просто дати користувачеві написати лист — в підтримку, наприклад.
Підводний камінь: MFMailComposeViewController недоступна на симуляторі та на пристроях без налаштованої пошти. Завжди перевіряємо MFMailComposeViewController.canSendMail() перед показом, інакше крах.
Сценарій 2: Трансакційні листи через API. Реєстрація, скидання пароля, уведомлення про замовлення — листи відправляються з сервера, додаток тільки ініціює запит. Вибір провайдера:
| Провайдер | SDK | Free tier |
|---|---|---|
| SendGrid | REST API + офіційний SDK | 100 листів/день |
| Mailgun | REST API | 100 листів/день |
| Amazon SES | AWS SDK | 62k листів/місяць (в AWS) |
| Postmark | REST API | Немає безплатного |
Мобільний додаток робить запит на свій backend (POST /api/send-email), backend викликає API провайдера. API ключі ніколи не зберігаються в додатку.
Сценарій 3: Читання та відправка пошти в інтерфейсі додатка. Повноцінний поштовий клієнт всередині додатка — це IMAP/SMTP або Graph API (Outlook) / Gmail API. Для Gmail: авторизація через OAuth 2.0, отримання списку листів через users.messages.list, тіл через users.messages.get. Квоти API Gmail — 250 одиниць за запит, обмеження 1 млрд одиниць на день на проект. При активному використанні потрібно стежити.
Робота з вложеннями
Вложення в мобільному контексті вимагають обережності. На iOS файли з UIDocumentPickerViewController доступні через security-scoped bookmarks і вимагають явного виклику startAccessingSecurityScopedResource() / stopAccessingSecurityScopedResource(). Без цього отримуємо NSCocoaErrorDomain код 257. На Android з API 30+ прямий доступ до /sdcard закритий — тільки через MediaStore або ACTION_OPEN_DOCUMENT.
Для завантаження вложень — потокова загрузка з прогресом, URLSession.downloadTask на iOS або OkHttp з ResponseBody.byteStream() на Android. Не буферизуємо все в пам'яті, якщо вложення може бути великим.
Push-уведомлення про нові листи
Для real-time уведомлень про вхідні листи IMAP IDLE тримає TCP-з'єднання — на мобільному це убиває батарею. Правильний шлях: сервер слухає IMAP IDLE, при новому листі відправляє push через FCM/APNs. Додаток отримує пуш, робить запит та оновлює список.
Оцінка сроків: простора інтеграція відправки трансакційних листів — 2-3 дні. Вбудований поштовий клієнт з IMAP/OAuth — від 3 до 6 тижнів.







