1 мая 2024 компания Microsoft официально прекратила поддержку Xamarin.Forms. Альтернативой они называют MAUI, который всё ещё очень и очень сырой. Нельзя так просто взять и перенести свое приложение на новые рельсы - у платформ разные подходы к написанию кода. Так как выкручиваться в таком случае тем, у кого есть legacy проекты на Xamarin.Forms, но при этом нет возможности перевести их на MAUI?
Предисловие
В 2020 году я начал работу над крупным пет-проектом на Xamarin.Forms. Работал по вечерам, после работы. Закончил разработку в 2025 году. Поскольку всё это время я вел разработку через Android-эмулятор, то о проблемах с iOS проектом я даже и не подозревал. Каково было мое удивление, когда я попросту даже не смог скомпилировать iOS приложение на маке...
Проблема 1: невозможно скомпилировать iOS проект
Apple выпускает мажорные обновления Xcode каждый год, а вместе с ним обновляется и инструментарий. Только вот в Xcode 16 они решили "выпилить" часть компонентов, без которых сборка Xamarin-приложения невозможна. Чаще всего это характеризуется ошибкой HE0004: Could not load the framework 'IDEDistribution'
Решений у проблемы 2:
Установить Xcode 15.2 в дополнение к актуальной вашей версии. Это последняя версия, имевшая полную совместимость по пакетам с Xamarin. Далее необходимо выбрать эту версию в системе командой
sudo xcode-select -s /Applications/Xcode_15_2.app/Contents/Developer
. Также необходимо в настройках JB Rider перейти в настройки -> Build, execution, deployment -> Apple Platforms -> Xcode Path, выбрать там версию 15.2(Рекомендуется) Можно скопировать недостающие фреймворки внутри Xcode 16+. Для этого в терминале последовательно выполняем команды:
cd /Applications/Xcode.app/Contents/SharedFrameworks/IDEDistribution.framework/Versions/A
sudo mkdir Frameworks
sudo cp -r /Applications/Xcode.app/Contents/SharedFrameworks/AppThinning.framework ./Frameworks
На этом этапе ошибки компиляции должны исчезнуть. Но начинается следующий этап - развертывание на устройстве
Проблема 2: ошибка MT1045 при развертывании приложения на iPhone
После успешной компиляции начинается развертывание приложения на вашем устройстве. Тут вы с большой долей вероятности получите ошибку "Failed to install application on device iPhone Username: error MT1045: Failed to execute 'devicectl': 'devicectl...". Лечится проблема довольно легко:
Открываем Xcode
Создаем там любой Hello World проект
Устанавливаем ему такой же Bundle ID, как и у вашего Xamarin.iOS проекта
Устанавливаем Hello World приложение на свой iPhone
Возвращаемся в JB Rider и устанавливаем свое Xamarin приложение
Проблема 3: PrivacyInfo.xcprivacy вложенных фреймворков
В 2025 году Apple решила дополнительно "позаботиться" о приватности пользователей. Компания внедрила требование по размещению в своем проекте файла PrivacyInfo.xcprivacy с описанием политики сбора персональных данных.
Пример содержимого такого файла:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "
http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist
version="1.0"><dict> <key>NSPrivacyTracking</key> <false/></dict></plist>
Проблема заключается в том, что все ваши nuget-пакеты, имеющие выход в сеть, должны также отчитаться этим файлом. Как вы понимаете, с этим проблемы... Вы не сможете обновиться до последней версии пакетов, где есть этот файл, так как актуальные версии пакетов не дружат с Xamarin.Forms... Без этого файла вы не сможете загрузить .ipa в AppStore. В случае отправки приложения вы получите ошибку ITMS-91061: Missing privacy manifest.
Как же решить проблему:
Создаем в своем Xamarin.iOS проекте файл PrivacyInfo.xcprivacy, устанавливаем ему свойство "BuildAction" в значение "BundleResource", вставляем в файл значение из примера выше
Открываем Info.plist и устанавливаем там новую версию вашего релиза
Выполняем сборку проекта в JB Rider в конфигурации Release под iPhone (не симулятор!)
Открываем Visual Studio for Mac -> Ваш проект -> View Archives/Прсмотр архивов
Публикуем ipa приложение на рабочий стол
Через Finder находим приложение на рабочем столе и меняем ему расширение с .ipa на .zip
Распаковываем содержимое zip-файла на рабочий стол. Должна распаковаться папка Payload
Заходим в папку Payload и кладем в нее Entitlements.plist из Xamarin.iOS проекта. Если в Entitlements.plist нет информации об идентификаторе приложения, то нужно добавить туда ключ application-identifier со значением <ID команды>.<Bundle ID> . Пример: D2A22DCJF8.ru.keaty.KeatyApp
Правый клик по вашему .app приложению -> "Просмотр содержимого пакета"
Находим там файл PrivacyInfo.xcprivacy и копируем его
Открываем папку Frameworks и вставляем скопированный файл в каждый фреймворк
Вызываем скрипт sign_prod_app.sh (смотри ниже) командой sudo sh sign_prod_app.sh с рабочего стола. Предварительно проверяем, что внутри скрипта указан правильный сертификат и имя приложения
Отправляем приложение в App Store через Transporter App
Исходный код скрипта sign_prod_app.sh:
#!/bin/bash
set -e
CODESIGN_IDENTITY="Apple Distribution: Your Certificate name (Your cert ID)"
APP_PATH="Payload/Your app file name.app"
ENTITLEMENTS_PATH="Payload/Entitlements.plist"
TIME_SUFFIX=$(date +"%H%M%S")
IPA_NAME="App_resigned_$TIME_SUFFIX.ipa"
if [ ! -d "Payload" ]; then
echo "❌ Ошибка: папка Payload не найдена!"
exit 1
fi
if [ ! -d "$APP_PATH" ]; then
echo "❌ Ошибка: .app не найдена!"
exit 1
fi
if [ ! -f "$ENTITLEMENTS_PATH" ]; then
echo "❌ Ошибка: Entitlements.plist не найден по пути $ENTITLEMENTS_PATH"
exit 1
fi
echo "? Подпись фреймворков"
for fw in "$APP_PATH"/Frameworks/*.framework; do
if [ -d "$fw" ]; then
echo "? Подписываю фреймворк: $(basename "$fw")"
codesign -f -s "$CODESIGN_IDENTITY" --timestamp "$fw"
fi
done
echo "? Подписываю .app с Entitlements"
codesign -f -s "$CODESIGN_IDENTITY" --timestamp --entitlements "$ENTITLEMENTS_PATH" "$APP_PATH"
echo "? Проверка подписи"
codesign --verify --deep --strict --verbose=2 "$APP_PATH"
echo "? Упаковка IPA: $IPA_NAME"
zip -qry "$IPA_NAME" Payload
echo "✅ IPA готова: $IPA_NAME"
Заключение
После проделанных действий ваше приложение должно успешно опубликоваться в AppStore. Неизвестно, сколько еще проживет данный способ, но в июле 2025 у меня успешно получилось опубликовать приложение.
Комментарии (5)
Fynjy007
22.07.2025 00:15Способ проживёт до мая 2026 года. Предварительно в, примерно апреле, придёт письмо счастья от эппла, что надо использовать свежий sdk и целиться в последние устройства.
UPD. Это из расчёта, что статья из песочницы свежая, а не пролежала там годик.
vovaza29 Автор
22.07.2025 00:15Статья свежая) Сам способ я вывел месяца 3 назад. По поводу SDK - сейчас ведь тоже Apple требует использовать его, а свежий сдк совсем не совместим с xamarin.forms. Тем не менее, я обошел ограничения через использование Xcode 15.2 + Свежий Xcode 16+
bodyawm
Благодарю за статью, хоть и преследую обратную цель: есть интерес поднять старую версию Xamarin.iOS времен iPhone 3/4, чтобы иметь возможность быстро писать приложеньки для ретро-айфонов и заодно портировать туда свой движок.
Пока что стопорюсь на том, что MonoDevelop просит валидный аккаунт Apple с оплаченным аккаунтом разработчика, думаю как бы пропатчить msbuild-скрипт и "вылечить" также, как и XCode (которым я успешно собрал и отлаживал приложение на джейлбрейкнутом 3GS с iOS 6)
Выдал инвайт
vovaza29 Автор
Аккаунт разработчика сейчас можно оплатить, привязав оплату МТС к Apple Pay