Как проверить версию SDK iOS, используемую для компиляции файла .ipa или .app

У меня есть только файлы .ipa(у меня нет сборки env) без какого-либо доступа к проекту. Я пытаюсь определить, были ли они созданы, связывая SDK 7. Есть ли способ или утилита для проверки версии SDK файлов .ipa/.app, скомпилированных с помощью?

Ответы

Ответ 1

Да. Сначала скопируйте ipa в безопасное место, например /tmp, и разархивируйте его:

cd /tmp/
cp ~/Music/iTunes/Mobile\ Applications/APPNAME.ipa .
unzip APPNAME.ipa

Затем используйте otool, чтобы увидеть, какие версии рамок он связывает:

otool -L Payload/APPNAME.app/APPNAME

Это даст вам следующие результаты:

Payload/APPNAME.app/APPNAME (architecture armv7):
    /usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)
    /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 992.0.0)
    /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 2372.0.0)
    /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (compatibility version 64.0.0, current version 600.0.0)
    /System/Library/Frameworks/AudioToolbox.framework/AudioToolbox (compatibility version 1.0.0, current version 359.0.0)
    /System/Library/Frameworks/MediaPlayer.framework/MediaPlayer (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 9.6.0)
    /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration (compatibility version 1.0.0, current version 499.0.0)
    /System/Library/Frameworks/CoreLocation.framework/CoreLocation (compatibility version 1.0.0, current version 1491.2.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 173.8.0)
    /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 793.0.0)

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

Для каждой структуры "текущая версия" является внутренним номером версии, который соответствует SDK, используемому при компиляции приложения. Для Foundation.framework вы можете посмотреть их в NSObjCRuntime.h. Он содержит кучу именованных констант, которые переводят между версиями iOS (или OS X) и номером версии, который предоставляет otool. Например:

#define NSFoundationVersionNumber_iOS_5_0  881.00
#define NSFoundationVersionNumber_iOS_5_1  890.10
#define NSFoundationVersionNumber_iOS_6_0  993.00
#define NSFoundationVersionNumber_iOS_6_1  993.00

Константы не включают текущую версию iOS. Вы можете найти это во время выполнения. Создайте новый тестовый проект и добавьте эту строку где-нибудь:

NSLog(@"Foundation version: %f", NSFoundationVersionNumber);

Это напечатает текущее значение. На iOS 7.0.4 я получаю 1047.220000. (Это работает для любой версии iOS и Foundation, но, если это возможно, легче искать значения в файле заголовка).

Цифры не всегда точно совпадают, потому что для каждой незначительной версии iOS нет констант. Но оба номера версий со временем увеличиваются. В этом случае "текущая версия" выше 992.0.0, и я знаю, что это приложение было скомпилировано для iOS 5.1.1. В зависимости от текущей версии вы можете сделать подобную интерполяцию. Для сравнения, в другом приложении, которое, как мне известно, было построено несколько лет назад, основная версия - 678.24.0. Глядя на это, подтверждает возраст приложения:

#define NSFoundationVersionNumber_iPhoneOS_2_0  678.24

Вероятно, можно найти номера версий для других фреймворков, но я не нашел для них соответствующие файлы заголовков. Если вам нужна версия SDK, версия Foundation сообщит вам, что вы хотите знать.

Addendum: Мэтт Стивенс указал мне, что также можно более прямо искать версию, делая это:

otool -l Payload/APPNAME.app/APPNAME | fgrep --after-context=3 LC_VERSION_MIN_IPHONEOS

Это дает вам следующие результаты:

      cmd LC_VERSION_MIN_IPHONEOS
  cmdsize 16
  version 5.0
      sdk 6.0

Это не работает в старом приложении iPhone OS 2.0, о котором я упоминал выше, но он работает над всем остальным, что я пробовал. Я не знаю, для какой версии это было добавлено, но он должен работать почти для каждого приложения, с которым вы сталкиваетесь.

Ответ 2

Есть и другой способ: открыть Info.plist

plutil -p Payload/APPNAME.app/Info.plist | grep DTSDKName

Это даст вам результат:

"DTSDKName" => "iphoneos7.0"

P.S. Этот способ работает и для очень древних приложений.