Реализация переноса данных при смене устройства (Device Migration)

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация переноса данных при смене устройства (Device Migration)
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Реализация переноса данных при смене устройства (Device Migration)

Пользователь купил новый телефон. Если перенос данных из приложения не работает — он начинает заново: настраивает профиль, теряет историю, переустанавливает покупки. Рейтинг приложения в App Store это не поднимает. Device migration — это не один механизм, а набор инструментов с разными компромиссами.

Платформенные инструменты

iOS: QuickStart (iPhone-to-iPhone прямой перенос через Bluetooth/WiFi) и iCloud Backup переносят данные приложения автоматически, если приложение их сохраняет корректно. Данные в Documents и Application Support включаются в резервную копию по умолчанию. Keychain с kSecAttrAccessible = kSecAttrAccessibleAfterFirstUnlock — переносится при iCloud Backup при условии kSecAttrSynchronizable = true.

Android: Google One Backup + Auto Backup переносит SharedPreferences, Room БД, файлы из getDataDir(). Настройка в AndroidManifest.xml:

<application
    android:allowBackup="true"
    android:dataExtractionRules="@xml/data_extraction_rules"
    android:fullBackupContent="@xml/backup_rules">
<!-- res/xml/data_extraction_rules.xml (Android 12+) -->
<data-extraction-rules>
    <cloud-backup>
        <include domain="database" path="app.db"/>
        <include domain="sharedpref" path="user_prefs.xml"/>
        <exclude domain="database" path="http_cache.db"/>
        <exclude domain="file" path="temp/"/>
    </cloud-backup>
</data-extraction-rules>

Серверный перенос через аккаунт

Самый надёжный подход — всё важное хранится на сервере, привязанное к аккаунту. Пользователь логинится на новом устройстве — получает все данные. Для приложений с авторизацией это стандарт.

Что должно быть на сервере:

  • Профиль пользователя
  • История действий
  • Покупки (обязательно — для восстановления)
  • Пользовательский контент
  • Настройки, если они влияют на бэкенд-логику

Что можно не синхронизировать:

  • Локальные настройки UI (тема, размер шрифта) — дешевле дать выбрать заново
  • Кэш (будет восстановлен автоматически)
  • Временные файлы

QR-код или код миграции

Для приложений без учётных записей — прямой перенос через QR или числовой код. Принцип: старое устройство генерирует временный токен или зашифрованный payload, новое устройство его сканирует.

// Генерация кода миграции
class MigrationCodeGenerator(private val exportManager: DataExportManager) {

    suspend fun generateMigrationCode(): MigrationCode {
        val exportedData = exportManager.exportUserData()
        val encryptedPayload = encryptWithTemporaryKey(exportedData)

        // Либо отправляем на сервер и получаем короткий код
        val code = api.createMigrationSession(
            payload = encryptedPayload,
            expiresIn = 10 * 60 // 10 минут
        )

        return MigrationCode(
            code = code.shortCode,     // "ABCD-1234"
            qrData = code.qrPayload,  // для QR-кода
            expiresAt = code.expiresAt
        )
    }
}

// Импорт на новом устройстве
suspend fun importFromCode(code: String): ImportResult {
    return try {
        val session = api.getMigrationSession(code)
        if (session.isExpired) return ImportResult.Expired

        val data = decryptPayload(session.encryptedPayload, session.tempKey)
        importManager.applyUserData(data)
        api.invalidateMigrationSession(code) // одноразовый — сразу инвалидируем
        ImportResult.Success
    } catch (e: Exception) {
        ImportResult.Error(e.message)
    }
}

Прямой peer-to-peer перенос

Для конфиденциальных данных, которые не должны проходить через сервер — прямой канал между устройствами:

iOS: MultipeerConnectivity framework — WiFi Direct или Bluetooth, без интернета. Android: Nearby Connections API (Google Play Services) — WiFi, Bluetooth, NFC.

// iOS: инициация сессии MultipeerConnectivity
let peerID = MCPeerID(displayName: UIDevice.current.name)
let session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
let advertiser = MCNearbyServiceAdvertiser(peer: peerID,
    discoveryInfo: ["appVersion": Bundle.main.appVersionString],
    serviceType: "myapp-migrate")

Для больших объёмов данных (фото, файлы) — только прямой канал, не через сервер. Скорость передачи по WiFi Direct — 20-50 МБ/с против 1-5 МБ/с через интернет.

Восстановление покупок

In-app purchases — отдельная история. Apple и Google хранят историю покупок на своей стороне.

// iOS: восстановление покупок StoreKit 2
for await result in Transaction.currentEntitlements {
    switch result {
    case .verified(let transaction):
        await updatePurchasedProducts(transaction.productID)
    case .unverified:
        break // подозрительная транзакция
    }
}
// Android: BillingClient
billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder()
        .setProductType(BillingClient.ProductType.SUBS)
        .build()
) { billingResult, purchases ->
    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
        purchases.forEach { purchase ->
            if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
                grantEntitlement(purchase.products)
            }
        }
    }
}

Кнопка «Восстановить покупки» — обязательна по гайдлайнам App Store.

Типичные ошибки

Перенос без валидации версии. Данные из приложения v1.0 импортируются в v3.5 без миграции схемы — крэш или некорректное состояние.

Незашифрованный QR. QR-код содержит plaintext данные пользователя — кто-то сфотографировал чужой экран.

Не инвалидируется миграционный токен. Код можно использовать повторно — данные утекут на третье устройство.

Реализация переноса данных с QR-кодом, серверной синхронизацией и восстановлением покупок: 2–3 недели. Стоимость рассчитывается индивидуально.