Для распространения приложения хотелось решить задачи:
- пользователь самостоятельно мог установить приложение на свое устройство
- только авторизированный пользователь мог устанавливать приложение
- простая публикация приложения на сервере
Опишу, как реализовывали и какие были трудности.
1.
С первым пунктом всё понятно, есть информация на эту тему. Т.е. создаем правильную ссылку на plist файл, а в нем должна быть волшебная ссылка на ipa архив приложения.
2.
Второй пункт казался не такой и сложной проблемой: создаем страницу аутентификации и авторизируем пользователя. Далее выдаем ему ссылку на установку/обновление приложения. PROFIT.
На деле оказалось всё не так просто. Сессия между Safari (я не говорю уже о других браузерах) и AppStore не шарится. Немного подумав можно и этот вопрос решить – сделать сессионные ключи и передавать их в параметрах ссылки. Просто делаем аналог куки, которые передаются GET’ом и имеют ограничения по времени жизни/количество раз использования. Далее меня ждал еще один маленький нюанс. По задумке ссылка на plist выглядела примерно так: httр://example.com/getapp?key=F00DBEE&type=plist, для получения самого приложения параметр type=ipa. Оказалось, что при обработке ссылок устройство учитывает только первый параметр, остальные попросту отбрасывает – обидно. Но где наше не пропадало – все интересующие данные можно и в один параметр сложить.
Стоит обратить внимание еще на одну мелочь – перед тем как получить приложение AppStore делает запрос на сервер методом HEAD, а только потом скачивает сам фал GET’ом. В связи с этой хитрой хитростью у меня сессия «протухала» тогда когда не надо. Да само приложение выплевывалось два раза, т.к. привык для контента использовать HEAD === GET.
3.
Уменьшение количества данных для публикации = уменьшение ошибок третьей стороны. В идеальном случае, что бы в обновлении фигурировал один файл приложения — ipa, но пользователю, зачастую, хочется знать, какие изменения были в приложение. Так что остановились на варианте ipa + описание изменений.
Для установки приложения нужен plist, в котором описаны предустановочные свойства. Этот XML файл выглядит абсолютно одинаково (с разницей в значениях параметров) для разных приложений.
<?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>items</key> <array> <dict> <key>assets</key> <array> <!-- обязательный. Ссылка на приложение --> <dict> <key>kind</key> <string>software-package</string> <key>url</key> <string>__URL__</string> </dict> <!-- не обязательный, иконка, которая показывается в момент скачивания приложения. При отсутствии будет серый квадрат --> <dict> <key>kind</key> <string>display-image</string> <key>needs-shine</key> <false/> <key>url</key> <string>__SMALL_IMAGE__</string> </dict> </array> <key>metadata</key> <dict> <!-- обязательный. внутренний идентификатор приложения --> <key>bundle-identifier</key> <string>__IDENTIFIER__</string> <!-- обязательный. Версия сборки приложения --> <key>bundle-version</key> <string>__VERSION__</string> <key>kind</key> <string>software</string> <!-- обязательный. Наименование приложения --> <key>title</key> <string>__TITLE__</string> </dict> </dict> </array> </dict> </plist>
Данные параметры можно получить из другого plist, находящегося в недрах ipa-файла (который является zip архивом) приложения — Info.plist. Недостаток только в том, что он бинарный. В MacOS есть хорошая консольная утилита plutil для конвертации форматов plist’ов, но не у всех на серверах стоят MacOS.
Решить эту проблему можно путем написания своего конвертера, либо собрать нативное приложение, либо воспользоваться Perl скриптом, Windows можно поставить приложения от Apple и найти консольную утилиту по адресу «C:\Program Files (x86)\Common Files\Apple\Apple Application Support\». Вариант со своей реализацией заманчив, но дорог. Я воспользовался Perl’ом. После конвертации бинарного plist получаем примерно такой XML:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>BuildMachineOSBuild</key> <string>14D73</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleDisplayName</key> <string>MyApp</string> <key>CFBundleExecutable</key> <string>MyApp</string> <key>CFBundleIcons</key> <dict> <key>CFBundlePrimaryIcon</key> <dict> <key>CFBundleIconFiles</key> <array> <string>i57.png</string> <string>i114.png</string> </array> </dict></dict> <key>CFBundleIdentifier</key> <string>com.company.MyApp.ios</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>MyApp</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleSupportedPlatforms</key> <array> <string>iPhoneOS</string> </array> <key>CFBundleVersion</key> <string>1.0.3</string> <!-- еще много ключей и их значений, который в данной статье не интересны --> </dict> </plist>
Из описания нам интересны: CFBundleVersion, CFBundleIdentifier, CFBundleDisplayName. Это наименование, версия, идентификатор приложения соответственно. Можно бонусом еще и иконку вытянуть. Для получения значений используем такой XPath /plist/dict/key[contains(text(),’__KEY__
‘)]/following-sibling::string[1]/text() где __KEY__
необходимые ключи.
Таким образом можно распространять не только Enterprise, но и AdHoc без особых проблем.
Обновление приложения.
Следить за обновлением приложения должно само приложение, т.к. оно не является частью AppStore. Да и вообще за приложением b2b нужно следить очень внимательно, оно еще может не перенестись с одного устройства на другое при дампе через iTunes. Для непосредственного обновления приложения из самого приложения необходимо открывать в Safari волшебную ссылку на манифест (plist) файл, которая начинается так itms-services://?action=download-manifest&url=.
В качестве заключения.
В данной реализации, быть может, только один костыль — использование стороннего приложения для чтения info.plist, остальные «телодвижения» можно совершить без особых проблем на всех (большинстве) платформ/технологий и т.д.
ссылка на оригинал статьи http://habrahabr.ru/post/205780/
Добавить комментарий