Почему не устанавливаются AdHoc приложения в iOS 15
История
Не так давно Apple зарелизила iOS 15 и, для большинства приложений которые мы делаем в Noveo, процесс миграции прошел довольно гладко. Нативные разрабочики предпочитают как можно скорее переехать на новый Xcode, и занимаются процессом адаптации приложений начиная с первых более-менее стабильных бета-версий iOS. Но разработчики кроссплатформенных решений, в силу сильной зависимости от стороннего фреймворка, не спешат с обновлением Xcode и пытаются оставаться на предыдущей стабильной версии.
Специально для них у нас есть билд машины со старым Xcode (например, 12.1) и так получилось, что выпущенные этой машиной AdHoc и Enterprise билды перестали устанавливать или запускаться (если уже были установлены) после обновления девайса до iOS 15. При попытке установить, пользователи получали уведомление «Разработчику необходимо обновить данное приложение, чтобы оно работало с этой версией iOS.» Что не так и как именно нужно обзвонить проблему решать пришлось мне.
Ищем источник проблемы
Как видно из скриншота, попап не содержит ни какой дополнительной информации об источнике проблемы и быстрый гуглеж не даёт четкого понимания почему такое происходит. Люди пишут разные причины или предположения о них, начиная от использования UIWebView (deprecated), заканчивая форматом подписи, но никак не сходятся во мнении. Предполагаю, что относительно небольшой процент пользователей использует AdHoc и Enterprise распространение, поэтому кейсов не так много и определенного ответа нет. Перебирать разные варианты не по мне, так что нужно искать точную причину.
Когда нам не пишут причины проблемы на на экране, мы лезем в логи! Открываем приложение Console (не путать с терминалом) и подключаем свой девайс. Находим его в списке слева, стартуем снятие логов, попутно отфильтровав ошибки и включив вывод только от installd (сервис установки приложений в iOS). Запускаем установку приложения на девайсе и ждем.
О! Источник проблемы найден уже через минуту. Пользователи на StackOverflow были правы насчет подписи. Осталось понять как это лечить и почему такое привходит на относительно свежей, не скинутой со счетов компанией Apple, Xcode 12.x.
Причины
После небольшого поиска информации в необъятном интернете, я наконец-то попадаю на страницу из документации Apple, где все четко и последовательно описано. Для тех, кому лень читать текст на английском, я тут кратко опишу проблему и решение.
Итак, начиная с iOS 15, операционная система требует новой версии цифровой подписи (версии 20400 и выше) и указания каких-то дополнительных entitlements в метаданных цифровой подписи. Давайте убедимся, что у нас действительно такая проблема. Для этого, нужно скачать IPA файл, разарихивировать его и воспользоваться утилитой codesign:
$ unzip my app.ipa -d myapp
$ codesign -dv myapp/Payload/MyApp.app
Executable=/Users/ksidorov/Downloads/myapp/Payload/MyApp.app/myapp
Identifier=CertificateID
Format=app bundle with Mach-O universal (armv7 arm64)
CodeDirectory v=20400 size=61615 flags=0x0(none) hashes=1917+5 location=embedded
Signature size=4793
Signed Time=18 Jul 2019, 16:14:53
Info.plist entries=45
TeamIdentifier=XXXXXXXXXX
Sealed Resources version=2 rules=10 files=663
Internal requirements count=1 size=172
Нас интересует строчка, начинающаяся с CodeDirectory. Там указана версия 20400, что является ОК для iOS 15. На данный момент актуальная версия — это 20500, 20400 еще поддерживается, а те, что ниже — уже нет.
Хорошо, далее давайте выясним про отсутствующие entitlements накинув еще буковок v в ключи:
$ codesign -dvvvvv myapp/Payload/MyApp.app
...
Executable Segment base=0
Executable Segment limit=5947392
Executable Segment flags=0x11
Page size=4096
-5=64203b52bcae912f72da800d8f5ba398f18836e21f5bf5420100c2d80596a533
-4=0000000000000000000000000000000000000000000000000000000000000000
-3=9a769c2a1f43913f3debfef5dbabf7948f5b5bdf8727a8045e72d5e389d0ba1b
-2=6691168b40a4cc2b8fd5dc03ffe9b50ac20d8069856167fba9f1540b00a5b2b6
CDHash=50273bc68865c7fdf98e788149240977ad1e3076
Signature size=4793
...
Для того, чтобы понять есть ли DER entitlements в подписи, достаточно бегло взглянуть на хеши в блоке Page size. Если вы видите хеш -5, но у вас нет хеша -7 или этот хеш заполнен нулями, то необходимые entitlements отсутствуют.
Как это исправить
На самом деле, виной устаревшей подписи является не сам Xcode, а версия MacOS. К сожалению, на сборочных нодах с Xcode 12.x мы не обновили MacOS до 11 и сборщик работал на 10.15. Он хоть и подписывал приложения валидной версией (20400), но не включал те самые DER entitlements.
Соответственно, самый простой способ — обновить MacOS и запустить сборку заново. Но если обновиться возможности нет, то можно переподписать приложение, явно указав что нужны entitlements:
$ unzip my app.ipa -d myapp
$ codesign -s "iPhone Distribution: Your Certificate ID" -f --preserve-metadata --generate-entitlement-der myapp/Payload/MyApp.app
$ zip -qr app_fixed.ipa myapp/Payload
Конечно же, для исправления подписи вам потребуется тот же сертификат, которым было подписано приложение (точнее, один из тех, которые были указаны в провижен файле при оригинальной подписи).
Случай очень частный, но, надеюсь, кому-нибудь эта мини-статья окажется полезной.
Спасибо, все понял