SDK Обновление приложений для Unity (версия 10.1.0)
Общие сведения
RuStore In-app updates SDK поддерживает актуальную версию приложения на устройстве пользователя. Это помогает пользователю увидеть обновления, оценить улучшение производительности и результат исправления ошибок.
Пример реализации
Используйте RuStore In-app updates SDK для реализации различных способов обновлений. В настоящий момент поддерживаются: отложенное, тихое (без UI от RuStore) и принудительное обновление.
Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать SDK обновлений.
Пользовательские сценарии
- Отложенное обновление
- Принудительное обновление
- Тихое обновление



Подключение в проект
- Установка через Package Manager
- Установка через .unitypackage
- Клонирование репозитория
Для подключения скачайте со страницы релизов пакеты:
ru.rustore.core-version.tgzru.rustore.update-version.tgz
Импортируйте пакеты в проект через Package Manager (Window → Package Manager → + → Add package from tarball...).
Если вы используете операционную систему macOS, измените настройки утилиты архивации. В настройках Archive Utility снимите флажок Keep expanding if possible. В противном случае архив проекта будет скачан некорректно.
Для корректной обработки зависимостей SDK выполните следующие настройки.
-
Откройте настройки проекта: Edit → Project Settings → Player → Android Settings.
-
В pазделе Publishing Settings включите следующие настройки.
- Custom Main Manifest.
- Custom Main Gradle Template.
- Custom Gradle Properties Template.
-
В разделе Other Settings настройте:
- package name.
- Minimum API Level = 24.
- Target API Level = 34.
Для подключения скачайте файл RuStoreUnityAppUpdateSDK-version.unitypackage со страницы релизов и импортируйте его в проект (Assets → Import Package → Custom Package). Зависимости подключаются автоматически с помощью External Dependency Manager (включен в SDK).
Если вы используете операционную систему macOS, измените настройки утилиты архивации. В настройках Archive Utility снимите флажок Keep expanding if possible. В противном случае архив проекта будет скачан некорректно.
Для корректной обработки зависимостей SDK выполните следующие настройки.
-
Откройте настройки проекта: Edit → Project Settings → Player → Android Settings.
-
В pазделе Publishing Settings включите следующие настройки.
- Custom Main Manifest.
- Custom Main Gradle Template.
- Custom Gradle Properties Template.
-
В разделе Other Settings настройте:
- package name.
- Minimum API Level = 24.
- Target API Level = 34.
Подключение зависимостей
- Автоматическое подключение зависимостей
- Ручное подключение зависимостей
Зависимости Android-сборки подключаются автоматически с помощью инструмента External Dependency Manager.
Для автоматического решения зависимостей воспользуйтесь командой: Assets → External Dependency Manager → Android Resolver → Force Resolve. Эту операцию следует выполнять каждый раз при добавлении новых версий плагинов или пересоздании файлов Assets / Plugins / Android / mainTemplate.gradle и Assets / Plugins / Android / settingsTemplate.gradle.
-
При установке плагинов RuStore через *.unitypackage External Dependency Manager не требует специальной установки.
-
При установке плагинов RuStore через Package Manager выполните следующие действия:
- Откройте вкладку плагина RuStore Core в окне менеджера пакетов: Window → Package Manager → Packages RuStore → RuStore Core.
- Перейдите на вкладку Samples.
- Импортируйте сэмпл External Dependency Manager.
-
Последнюю версию External Dependency Manager также можно получить из репозитория разработчика на GitHub:
- Откройте окно менеджера пакетов: Window → Package Manager → + → Add package from git URL....
- Используйте ссылку https://github.com/googlesamples/unity-jar-resolver.git?path=/upm для подключения пакета.
- Для устранения ошибки "Google.IOSResolver.dll will not be loaded" установите модуль сборки iOS для вашей версии Unity: UnityHub → Installs → Ваша версия Unity → Add modules → iOS Build Support.
Assembly 'Packages/com.google.external-dependency-manager/ExternalDependencyManager/Editor/1.2.182/Google.IOSResolver.dll' will not be loaded due to errors:
Unable to resolve reference 'UnityEditor.iOS.Extensions.Xcode'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
- Откройте файл mainTemplate.gradle: Assets / Plugins / Android / mainTemplate.gradle. В секции dependencies добавьте строки:
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'ru.rustore.sdk:appupdate:x.y.z'
Пример оформления секции dependencies:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'ru.rustore.sdk:appupdate:x.y.z'
}
где x.y.z – номер версии пакета SDK.
- Откройте файл settingsTemplate.gradle: Assets / Plugins / Android / settingsTemplate.gradle. В секции dependencyResolutionManagement repositories добавьте строки:
maven {
url "https://artifactory-external.vkpartner.ru/artifactory/maven"
}
Пример оформления секции dependencyResolutionManagement repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/")
maven {
url "https://artifactory-external.vkpartner.ru/artifactory/maven"
}
mavenLocal()
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
}
}
Обновление
Версии плагина 6.1.0 и выше содержат измененную структуру директорий. Измененная структура позволяет использовать преимущества раздельных сборок частей проекта Assembly definitions.
Перед установкой обновления выполните удаление следующих папок.
- Assets > RuStoreSDK > AppUpdate > Editor.
- Assets > RuStoreSDK > Common > Editor.

После удаления импортируйте новый .unitypackage в проект как при обычной установке (Assets > Import Package > Custom Package).
Репозиторий содержит исходный код плагина и демонстрационный проект, содержащий представление работы всех методов SDK.
Не используйте кнопку "Код → Скачать" на сайте GitFlic – этот метод не загружает файлы из Git LFS.
Перед клонированием репозитория скачайте и установите инструменты:
После установки выполните в командной строке:
git lfs install
Для клонирования репозитория воспользуйтесь набором команд:
git clone https://gitflic.ru/project/rustore/unity-rustore-appupdate-sdk.git
cd unity-rustore-appupdate-sdk
git lfs pull
Создание менеджера обновлений
RuStoreAppUpdateManager.Instance.Init();
Проверка наличия обновлений
Прежде чем запрашивать обновление, проверьте, доступно ли обновление для вашего приложения.
Для проверки наличия обновлений вызовите метод getAppUpdateInfo().
При вызове данного метода проверяются следующие условия:
- На устройстве пользователя установлена актуальная версия RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore
- Приложению RuStore разрешена установка приложений.
- Пользователь авториз ован в RuStore.
В ответ на данный метод вы получите объект AppUpdateInfo, который будет содержать в себе
информацию о необходимости обновления.
Запросите этот объект заранее и закэшируйте его, чтобы запросить у
пользователя запуск скачивания обновления без задержки и в удобный для пользователя момент времени.
RuStoreAppUpdateManager.Instance.GetAppUpdateInfo(
onFailure: (error) => {
// Handling error
},
onSuccess: (info) => {
// Process update info
}
);
Объект AppUpdateInfo содержит набор параметров, необходимых для определения доступности обновления.
updateAvailability — доступность обновления:
UNKNOWN (int == 0)— по умолчанию;UPDATE_NOT_AVAILABLE (int == 1)— обновление не нужно;UPDATE_AVAILABLE (int == 2)— обновление требуется загрузить или обновление уже загружено на устройство пользователя;DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS (int == 3)— обновление уже скачивается или установка уже запущена.
installStatus — статус установки обновления, если пользователь уже устанавливает обновление в текущий момент времени:
UNKNOWN (int == 0)— по умолчанию;DOWNLOADED (int == 1)— скачано;DOWNLOADING (int == 2)— скачивается;FAILED (int == 3)— ошибка;PENDING (int == 5)— в ожидании.
Запуск скачивания обновления возможен только в том случае, если поле updateAvailability
содержит значение UPDATE_AVAILABLE.
Скачивание и установка обновлений
Использование слушателя
После подтверждения доступности обновления (AppUpdateInfo) вы можете запр осить статус
скачивания обновления — для этого запустите слушатель статуса скачивания обновления.
Проверка статуса скачивания обновления
Используйте метод RegisterListener().
RuStoreAppUpdateManager.Instance.RegisterListener(listener);
listener — объект класса, реализующего интерфейс IInstallStateUpdateListener:
public interface InstallStateUpdateListener {
public void OnStateUpdated(InstallState state);
}
Объект state описывает текущий статус скачивания. Ниже представлено содержимое объекта.
installStatus — статус установки обновления, если пользователь уже устанавливает обновление в текущий момент времени:
UNKNOWN (int == 0)— по умолчанию;DOWNLOADED (int == 1)— скачано;DOWNLOADING (int == 2)— скачивается;FAILED (int == 3)— ошибка;PENDING (int == 5)— в ожидании;
В SDK обновлений нет о собого статуса для ситуации, когда пользователь отменил скачивание обновления. Если пользователь прервал обновление на этапе скачивания, installStatus возвращает исходный статус UNKNOWN (0) с кнопкой Скачать.
Если пользователь уже скачал обновление, но отменил установку, то installStatus вернёт значение DOWNLOADED (1).
Рассмотрим следующие варианты.
Пользователь начал скачивание обновления, но отменил скачивание — в этом случае:
updateAvailability— UPDATE_AVAILABLE (2);installStatus— UNKNOWN (0).Пользовательскачал файл обновления, но не стал его устанавливать — в этом случае:updateAvailability— UPDATE_AVAILABLE (2);installStatus— DOWNLOADED (1).bytesDownloaded— количество загруженных байт;totalBytesToDownload— общее количество байт, которое необходимо скачать;installErrorCode— код ошибки во время скачивания. Коды ошибок описаны в разделе Обработка ошибок.
Удаление слушателя
Если необходимости в слушателе больше нет, воспользуйтесь методом удаления слушателя unregisterListener(), передав в метод ранее зарегистрированный слушатель.
RuStoreAppUpdateManager.Instance.UnregisterListener(listener);
Запуск скачивания обновления
Отложенное обновление
Запуск сценария обновления
Для запуска скачивания обновления приложения вызовите метод StartUpdateFlow с параметром UpdateType.FLEXIBLE:
RuStoreAppUpdateManager.Instance.StartUpdateFlow(
UpdateType.FLEXIBLE,
onFailure: (error) => {
// Handling error
},
onSuccess: (resultCode) => {
// Handle flow result
}
);
Объект AppUpdateInfo после однократного использования становится невалидным. Для повторного вызова метода StartUpdateFlow() запросите AppUpdateInfo, снова используя метод GetAppUpdateInfo().
Если пользователь подтвердил скачивание обновления, тогда resultCode = UpdateFlowResult.RESULT_OK, если отказался, то resultCode = UpdateFlowResult.RESULT_CANCELED.
После получения статуса InstallStatus.DOWNLOADED вы можете вызвать метод установки обновления CompleteUpdate().
Рекомендуется уведомить пользователя о готовности обновления к установке.
Метод может вернуть ошибку.
Принудительное обновление
Запуск сценария обновления
После получения AppUpdateInfo вы можете проверить доступность принудительного обновления.
var isImmediateUpdateAllowed = RuStoreAppUpdateManager.Instance.IsImmediateUpdateAllowed();
Результат функции IsImmediateUpdateAllowed рекомендуется использовать для принятия решения о запуске принудительного обновления, но данный результат не влия ет на возможность запуска сценария. Необходимость запуска сценария обновления может происходить по вашей внутренней логике.
Для запуска сценария обновления используйте метод StartUpdateFlow с параметром UpdateType.IMMEDIATE:
RuStoreAppUpdateManager.Instance.StartUpdateFlowImmediate(
UpdateType.IMMEDIATE,
onFailure: (error) => {
// Handling error
},
onSuccess: (resultCode) => {
// Handle flow result
}
);
resultCode (Int):
UpdateFlowResult.RESULT_OK (-1)— обновление выполнено, код может не быть получен, т. к. приложение в момент обновления завершается.UpdateFlowResult.RESULT_CANCELED (0)— флоу прервано пользователем, или произошла ошибка. Предполагается, что при получении этого кода следует завершить работу приложения.UpdateFlowResult.RESULT_ACTIVITY_NOT_FOUND (2)— RuStore не установлен, либо установлена версия, которая не поддерживает принудительное обновление (RuStore versionCode<191).
throwable - ошибка старта сценария обновления.
При успешном обновлении дальнейших действий не требуется.
Тихое обновление
Запуск сценария обновления
Для запуска скачивания обновления приложения необходимо вызвать метод StartUpdateFlow с параметром UpdateType.SILENT.
RuStoreAppUpdateManager.Instance.StartUpdateFlowSilent(
UpdateType.SILENT,
onFailure: (error) => {
// Handling error
},
onSuccess: (resultCode) => {
// Handle flow result
}
);
При вызове onSuccess с resultCode = UpdateFlowResult.RESULT_OK будет зарегистрирована задача на скачивание обновления.
В данном сценарии может быть вызван только onSuccess с resultCode = UpdateFlowResult.RESULT_OK, либо onFailure.
После вызова метода вы можете следить за статусом скачивания обновления в слушателе.
После получения статуса InstallStatus.DOWNLOADED вы можете вызвать метод установки обновления CompleteUpdate().
Рекомендуется уведомить пользователя о готовности обновления к установке.
Для тихого обновления рекомендуется реализовать свой интерфейс.
Установка обновления
Для запуска установки обновления используйте метод CompleteUpdate. Обновление происходит через нативный инструмент Android.
Рекомендуется уведомить пользователя о готовности обновления к установке.
Гибкое завершение обновления
Обновление с UI от RuStore:
-
Пользователю будет показан UI-диалог завершения обновления.
-
В случае успешного обновления приложение будет перезапущено.
Метод CompleteUpdate должен быть вызван с параметром FLEXIBLE.
RuStoreAppUpdateManager.Instance.CompleteUpdate(
UpdateType.FLEXIBLE,
onFailure: (error) => {
// Handling error
}
);
UpdateType — тип процедуры завершения обновления:
FLEXIBLE— обновление и перезапуск приложения.
Тихое завершение обновления
Обновление без UI от RuStore:
- UI-диалог завершения обновления не будет показан.
- В случае успешного обновления приложение будет закрыто.
Метод CompleteUpdate должен быть вызван с параметром SILENT.
RuStoreAppUpdateManager.Instance.CompleteUpdate(
UpdateType.SILENT,
onFailure: (error) => {
// Handling error
}
);
UpdateType — тип процедуры завершения обновления:
SILENT— обновление и закрытие приложения.
Обработка ошибок
Если вы получили в ответ onFailure, не рекомендуется самостоятельно отображать ошибку пользователю.
Отображение ошибки может негативно повлиять на пользовательский опыт.
Ниже представлена структура ошибки:
public class RuStoreError {
public string name;
public string description;
}
Возможные ошибки
RuStoreNotInstalledException— на устройстве пользователя не установлен RuStore;RuStoreOutdatedException— версия RuStore, установленная на устройстве пользователя, не под держивает данный SDK;RuStoreUserUnauthorizedException— пользователь не авторизован в RuStore;RuStoreException— базовая ошибка RuStore, от которой наследуются остальные ошибки;RuStoreInstallException(public val code: Int)— ошибка скачивания и установки.ERROR_UNKNOWN(Int = 4001)— неизвестная ошибка.ERROR_DOWNLOAD(Int = 4002)— ошибка при скачивании.ERROR_BLOCKED(Int = 4003)— установка заблокированна системой.ERROR_INVALID_APK(Int = 4004)— некорректный APK обновления.ERROR_CONFLICT(Int = 4005)— конфликт с текущей версией приложения.ERROR_STORAGE(Int = 4006)— недостаточно памяти на устройстве.ERROR_INCOMPATIBLE(Int = 4007)— несовместимо с устройством.ERROR_APP_NOT_OWNED(Int = 4008)— приложение не куплено.ERROR_INTERNAL_ERROR(Int = 4009)— внутренняя ошибка.ERROR_ABORTED(Int = 4010)— пользователь отказался от установки обновления.ERROR_APK_NOT_FOUND(Int = 4011)— APK для запуска установки не найден.ERROR_EXTERNAL_SOURCE_DENIED(Int = 4012)— запуск обновления запрещён. Например, в первом методе вернулся ответ о том, что обновление недоступно, но пользователь вызывает второй метод.ERROR_ACTIVITY_SEND_INTENT(Int = 9901)— ошибка отправки intent на открытие активити.ERROR_ACTIVITY_UNKNOWN(Int = 9902)— неизвестная ошибка отрытия активити.
Список зависимостей для обновления приложения
ru.rustore.sdk:core:0.1.10— GNU Lesser General Public License v3.0;ru.rustore.sdk:analytics:0.1.5— GNU Lesser General Public License v3.0;org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20— The Apache Software License, Version 2.0;org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4— The Apache Software License, Version 2.0;androidx.core:core-ktx:1.9.0— The Apache Software License, Version 2.0;androidx.appcompat:appcompat:1.5.1— The Apache Software License, Version 2.0;androidx.activity:activity:1.5.1— The Apache Software License, Version 2.0.