TL; DR Ознакомьтесь с этой статьей для краткого изложения.
Для iOS у вас есть следующие опции:
- Используйте инструмент командной строки, такой как
defaults
на Mac или plistutil
в Linux, и вызывайте его из своего кода Java, используя ProcessBuilder
. - Используйте dd-plist библиотека для Java
- Используйте библиотеку justtestlah для Java (которая включает dd-plist и аналогичную библиотеку для приложений Android) Отказ от ответственности: Я являюсь автором этогоtool.
Короче говоря, если вам требуется только iOS, я предлагаю вариант 2, если вы хотите такой же подход для Android и iOS, я рекомендую вариант 3.
Объявление 1.
Это зависит от платформы и, следовательно, не идеально (IMO).Если вы выбираете только одну платформу для выполнения своих тестов или не возражаете против поддержки нескольких, а также не против установки дополнительных инструментов, это прекрасно работает.
Это команды для получения информации о версии.Аналогично, вы также можете запрашивать другие метаданные из пакетов приложения.
Mac OS:
defaults read /path/test.app/Info CFBundleShortVersionString
defaults read /path/test.app/Info CFBundleVersion
Linux:
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()" -
Этот подход, вероятно, наиболее полезен для использования.в сценариях оболочки (например, в конвейере CI).
Интеграция в Java-программу будет выглядеть примерно так (обратите внимание, что вам может понадобиться добавить дополнительную обработку ошибок, если вы решите использовать это):
String versionName = executeCommand("defaults read /path/test.app/Info CFBundleShortVersionString");
public String executeCommand(String command) {
LOG.info("Executing command {}", command);
String[] shellCommand = {"/bin/sh", "-c", command};
Process process;
try {
process = new ProcessBuilder(shellCommand).start();
return Stream.of(process.getErrorStream(), process.getInputStream())
.parallel()
.map(
(InputStream inputStream) -> {
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
return br.readLine(); // we only care about the first line
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.joining());
} catch (IOException exception) {
LOG.error(String.format("Error while executing command %s", command), exception);
}
return "";
}
Я сделалPoC для этого здесь .Хотя это работает нормально и имеет то преимущество, что не требует каких-либо дополнительных библиотек Java, я бы порекомендовал вместо этого один из других вариантов.
Объявление 2.
Добавьте dd-спишите JAR-файл в ваш путь к классам.Например, для Maven:
<properties>
<dd.plist.version>1.21</dd.plist.version>
</properties>
<dependencies>
<dependency>
<groupId>com.googlecode.plist</groupId>
<artifactId>dd-plist</artifactId>
<version>${dd.plist.version}</version>
</dependency>
</depdencies>
Затем выполните код следующим образом:
String appPath = "/path/test.app";
NSDictionary dictionary = (NSDictionary) PropertyListParser.parse(path);
String versionName = dictionary.objectForKey(“CFBundleShortVersionString”).toString();
String versionCode = dictionary.objectForKey(“CFBundleVersion”).toString();
Ad 3.
Добавьте justtestlah-mobile-tools
JAR-файл для вашего classpath.Для Maven:
<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();
Дополнительным преимуществом последнего является то, что вы можете использовать один и тот же код для APK, APP и даже IPAфайлы.