Легко извлекайте информацию о версии из пакетов APK, IPA и APP
Часто, особенно при запуске автоматизированных тестов мобильных приложений, важно убедиться, что используется правильная версия приложения. В этой статье описаны простые способы запроса информации о версии из пакетов приложений Android и iOS с помощью инструментов командной строки или библиотек Java. Оба подхода можно легко интегрировать в конвейер сборки.
Командная строка
Для Android один из подходов к синтаксическому анализу метаинформации из файла APK - это использовать aapt
примерно так:
aapt dump badging /path/test.apk
Это печатает много информации, поэтому нам нужно обрезать вывод до того, что нам интересно:
aapt dump badging test.apk | grep -o 'versionName=[^,]*' | cut -d'=' -f 2 | cut -d ' ' -f 1 | tr -d "'"
Точно так же мы можем запросить код версии (или любую другую информацию, если на то пошло):
aapt dump badging /path/test.apk | grep -o ‘versionCode=[^,]*’ | cut -d’=’ -f 2 | cut -d ‘ ‘ -f 1 | tr -d "'"
Если у нас есть приложение, установленное на устройстве (физическом или симуляторе), которое подключено через adb
, мы также можем запросить версию следующим образом:
adb shell dumpsys package package.of.the.app | grep versionName | cut -d'=' -f 2 | cut -d ' ' -f 1 adb shell dumpsys package package.of.the.app | grep versionCode | cut -d'=' -f 2 | cut -d ' ' -f 1
Для приложений iOS давайте сначала рассмотрим пакеты APP (используемые для симуляторов). Если у нас Mac OSX, мы можем использовать defaults
. Обратите внимание, что путь должен быть абсолютным:
defaults read /path/test.app/Info CFBundleShortVersionString defaults read /path/test.app/Info CFBundleVersion
В Linux нам нужен plistutil
и синтаксический анализатор XML, например xmllint
:
plistutil -i /path/test.app/Info | xmllint --xpath "//key[text()='CFBundleShortVersionString']/following-sibling::string[1]/text()" - plistutil -i /path/test.app/Info | xmllint --xpath "//key[text()='CFBundleVersion']/following-sibling::string[1]/text()"
Если мы хотим получить информацию о версии из файла IPA (используемого для физических устройств), мы должны сначала его распаковать. Затем мы можем запустить те же команды, что и выше:
# Unpack IPA file unzip -q /path/test.ipa -d /tmp/ipa # Mac OS defaults read /tmp/ipa/Payload/test.app/Info CFBundleShortVersionString defaults read /tmp/ipa/Payload/test.app/Info CFBundleVersion # Linux plistutil -i /tmp/ipa/Payload/test.app/Info | xmllint --xpath "//key[text()='CFBundleShortVersionString']/following-sibling::string[1]/text()" - plistutil -i /tmp/ipa/Payload/test.app/Info | xmllint --xpath "//key[text()='CFBundleVersion']/following-sibling::string[1]/text()" # Clean-up rm -rf /tmp/ipa
Путь Java
Один из способов получить информацию о версии из программы Java - использовать Runtime
или ProcessBuilder
для выполнения вышеуказанных команд оболочки. Однако это зависит от платформы и немного хрупко. Для этого необходимо, чтобы используемые инструменты (aapt
, plistutil
, xmllint
и т. Д.) Были доступны на машине, на которой выполняется код Java.
Поэтому предпочтительнее собственное решение Java. К счастью, есть библиотеки с открытым исходным кодом для всех наших нужд:
- Apk-parser: эта библиотека позволяет нам читать информацию из файлов APK.
- Dd-plist: эта библиотека может обрабатывать
plist
файлов, используемых для хранения метаинформации приложения iOS. - Zip4j: эта библиотека - один из многих вариантов работы с zip-файлами в Java.
Используя Maven, мы можем включить их в наш проект:
<properties> <dd.plist.version>1.21</dd.plist.version> <apk.parser.version>2.6.4</apk.parser.version> <zip4j.version>1.3.2</zip4j.version> </properties> <dependencies> <dependency> <groupId>com.googlecode.plist</groupId> <artifactId>dd-plist</artifactId> <version>${dd.plist.version}</version> </dependency> <dependency> <groupId>net.dongliu</groupId> <artifactId>apk-parser</artifactId> <version>${apk.parser.version}</version> </dependency> <dependency> <groupId>net.lingala.zip4j</groupId> <artifactId>zip4j</artifactId> <version>${zip4j.version}</version> </dependency> </depdencies>
Для Android мы можем просто получить информацию о версии следующим образом:
String appPath = "/path/test.apk"; ApkFile apkFile = new ApkFile(new File(appPath)); ApkMeta apkMeta = apkFile.getApkMeta(); String versionName = apkMeta.getVersionName(); String versionCode = apkMeta.getVersionCode().toString();
Для iOS код пакета APP выглядит следующим образом:
String appPath = "/path/test.app"; NSDictionary dictionary = (NSDictionary) PropertyListParser.parse(path); String versionName = dictionary.objectForKey(“CFBundleShortVersionString”).toString(); String versionCode = dictionary.objectForKey(“CFBundleVersion”).toString();
Если вместо этого мы имеем дело с файлом IPA:
String appPath = "/path/test.ipa"; # Unpack IPA file String tmpFolder = File.separator + "tmp" + File.separator + UUID.randomUUID().toString(); ZipFile zipFile = new ZipFile(appPath); zipFile.extractAll(tmpFolder); # Fetch version information NSDictionary dictionary = (NSDictionary) PropertyListParser.parse(new File(new File(tmpFolder + File.separator + "Payload").listFiles()[0].getAbsolutePath() + File.separator + "Info.plist")); String versionName = dictionary.objectForKey(“CFBundleShortVersionString”).toString(); String versionCode = dictionary.objectForKey(“CFBundleVersion”).toString(); # Clean-up Files.walk(Paths.get(tmpFolder)).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
Для простоты обработка исключений была удалена из приведенных выше примеров.
Полный код доступен здесь.
Универсальная библиотека
Приведенная выше демонстрация является частью justtestlah
тестовой среды. Вы можете использовать mobile-tools
JAR (который поставляется с минимальным количеством дополнительных зависимостей) для запроса версии и другой метаинформации из приложений Android и iOS. Импортируйте его следующим образом:
<properties> <justtestlah.version>1.3.2</justtestlah.version> </properties> <dependencies> <dependency> <groupId>io.github.martinschneider</groupId> <artifactId>justtestlah-mobile-tools</artifactId> <version>${justtestlah.version}</version> </dependency> </depdencies>
Затем просто используйте это так:
ApplicationInfo appInfo = new ApplicationInfoService().getAppInfo(appPath); String versionName = appInfo.getVersionName(); String versionCode = appInfo.getVersionCode(); String applicationName = appInfo.getApplicationName();
appPath
может указывать на любой файл APK, IPA или APP.