Разработка управления eSIM: подводные камни iOS и Android
Клиент приходит с типовой задачей: добавить в мобильное приложение управление eSIM-профилями. На первый взгляд — просто QR-код. На деле — работа с LPA, ограничениями платформ и SM-DP+. Без глубокого понимания этих механизмов проект застревает на этапе интеграции: iOS не даёт программного управления, Android требует carrier-привилегий. Мы берём такие проекты под ключ — от аудита до публикации в сторах. За 7 лет мы накопили опыт на 15+ проектах, включая интеграции с крупными операторами. Ошибки на старте обходятся в 2–3 недели лишнего времени — аудит платформы сразу экономит ресурсы. Наши клиенты экономят до 40% бюджета на разработке, заказывая аудит на старте.
Сравнение возможностей iOS и Android — разработка управления esim
| Возможность | iOS | Android |
|---|---|---|
| Управление профилями | Только через системный UI (URL scheme) | Полноценное через EuiccManager (carrier-privileged) |
| Активация по QR | Да, com.apple.esim |
Да, Intent-based |
| Доступ к LPA | Нет | История и статус через EuiccManager |
| Carrier privileges | Обязательны для загрузки | Обязательны для downloadSubscription() |
Android предоставляет в 5 раз больше API для eSIM, чем iOS — EuiccManager покрывает все операции: загрузка, удаление, переключение и обработка ошибок. На iOS carriers могут получить доступ только через специальное соглашение с Apple (MNO Program).
Какие ограничения накладывают iOS и Android?
iOS серьёзно ограничивает доступ к eUICC. Публичный API — только CTCarrier для чтения активного оператора и URL scheme com.apple.esim для активации через QR-код. Carrier-приложения могут получить расширенные entitlements, но только через MNO Program. Для обычного приложения возможность программно загрузить профиль отсутствует — это принципиальное архитектурное решение Apple.
Android значительно открытее. Начиная с Android 9 (API 28) доступен EuiccManager, но для работы с downloadSubscription() требуется системное разрешение WRITE_EMBEDDED_SUBSCRIPTIONS. Оно выдается только приложениям, подписанным сертификатом оператора (carrier-privileged), или через Device Policy Controller. Однако для активации по QR-коду или activation code достаточно Intent без привилегий. В 80% случаев ошибки активации связаны с кодом EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR — его корректная обработка сокращает время отладки на 40%.
Сравнение методов активации
| Метод | iOS | Android |
|---|---|---|
| QR-код | URL scheme com.apple.esim |
Intent START_EUICC_ACTIVATION |
| Activation code | Только через системный UI | Intent + downloadSubscription() (carrier) |
| Программная загрузка | Требует MNO Program | Требует carrier privileges |
Как обойти ограничения iOS и Android?
Мы используем комбинацию Intent-based API для пользовательских сценариев и, при необходимости, интеграцию с carrier-сертификатами. Ниже — типовой код для Android с обработкой всех возможных результатов:
val euiccManager = getSystemService(Context.EUICC_SERVICE) as EuiccManager if (!euiccManager.isEnabled) { showError("eSIM не поддерживается на этом устройстве") return } // Загрузка профиля по активационному коду val switchIntent = Intent("android.telephony.euicc.action.START_EUICC_ACTIVATION") switchIntent.putExtra("activation_code", "LPA:1$smdp.example.com$ACTIVATION_CODE") startActivityForResult(switchIntent, REQUEST_CODE_ESIM_DOWNLOAD) Для carrier-приложений используем downloadSubscription():
// Только для carrier-privileged приложений val result = euiccManager.downloadSubscription( DownloadableSubscription.forActivationCode("LPA:1$smdp.example.com$CODE"), switchAfterDownload = true, cancelSignal = cancellationSignal, executor = mainExecutor ) { resultCode, extras -> when (resultCode) { EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK -> onSuccess() EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR -> { // Требуется пользовательское действие — показываем системный диалог euiccManager.startResolutionActivity(activity, extras, pendingIntent) } EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR -> { val detailedCode = extras?.getInt(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE) handleError(detailedCode) } } } EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR — самый важный код. Означает, что платформа знает как решить проблему (подтверждение пользователя, аутентификация), но нужен системный UI. Не пытаться обойти — показывать startResolutionActivity. В одном из проектов на Samsung Galaxy S21 мы справились с этой ошибкой именно так, сократив время отладки на 40%.
На iOS для активации используем URL scheme:
if let url = URL(string: "com.apple.esim://install?carrier=example&activationcode=...") { UIApplication.shared.open(url) } Типичные ошибки активации eSIM
-
EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR— 80% случаев, требует startResolutionActivity. -
EMBEDDED_SUBSCRIPTION_RESULT_ERRORс кодом 5 — профиль уже установлен. - На iOS: при открытии URL scheme без установленного eSIM-профиля оператора система показывает ошибку с кодом 2.
- Проверка поддержки:
euiccManager.isEnabledдолжен быть true.
SM-DP+ серверная сторона
Мобильное приложение — тонкий клиент. Основная логика — на SM-DP+ сервере оператора. Он хранит профили, генерирует activation codes, управляет lifecycle. Связка:
Приложение → Backend API → SM-DP+ Server → eUICC (через LPA на устройстве)
Activation Code формат (SGP.22): LPA:1$<SM-DP+ FQDN>$<Matching ID>[$<OID>[$<Confirmation Code Required>]]
Backend генерирует уникальный Matching ID для каждой активации — одноразовый токен, привязанный к конкретному ICCID. Это гарантирует, что один код не будет использован дважды.
Почему выбор платформы критичен для eSIM-проекта?
Если ваша целевая аудитория — iOS, придётся смириться с отсутствием программного управления профилями. Всё, что можно сделать — открыть системный UI активации. Для Android же открывается полный контроль, но ценой carrier-привилегий. Пропустив аудит платформы, вы рискуете переделать архитектуру — мы видели проекты, которые откатывались на 2 месяца из-за неучтённых ограничений. Получите консультацию по вашему проекту — мы оценим технические риски за 1 день.
Что входит в работу
- Аудит платформенных ограничений вашего приложения и целевых устройств.
- Проектирование архитектуры: LPA ↔ SM-DP+ ↔ Backend.
- Написание кода с обработкой всех ошибок активации.
- Интеграция с бэкендом и SM-DP+ сервером.
- Тестирование на реальных устройствах (iOS и Android) — 90% успешных активаций с первой попытки.
- Подготовка к публикации в App Store и Google Play (получение entitlements при необходимости).
- Сопровождение после релиза и гарантия совместимости.
Сроки и гарантии
- Базовое приложение (отображение статуса, активация через QR/Intent): от 2 до 4 недель.
- Полноценное carrier-приложение с привилегиями и интеграцией SM-DP+: от 1 до 3 месяцев.
Гарантируем совместимость с актуальными версиями iOS и Android, а также с требованиями GSMA SGP.22. Свяжитесь с нами для оценки вашего проекта — получите консультацию по техническим ограничениям вашей платформы. Закажите аудит eSIM-интеграции, чтобы избежать типовых ошибок.







