- Что необходимо для push-уведомлений
- Что мы будем разбирать?
- Что нам понадобится?
- Intermediate certificates
- Вкратце об itunes connect
- Идентификаторы (identifiers)
- Краткий обзор
- Кратко о главном
- Обновить push-сертификат и сохранить текущее приложение app store
- Ориентировка по разделам
- Подготовка apple push notification ssl сертификата | heximal blog
- Понимание push-уведомлений
- Простенькое приложение
- Профили (provisioning profiles)
- Профили типа «development»
- Профили типа «distribution»
- Резюмируем
- Сертификаты (certificates)
- Сертификаты типа «development»
- Создание provisioning profile
- Терминология
- Устройства (devices)
- 🚧best practices
- 🚧previous certificate revokation
Что необходимо для push-уведомлений
Для интеграции push-уведомлений в приложение необходимо:
iPhone, iPad или iPod touch. Push-уведомления не работают в симуляторе, поэтому для тестирования нужен девайс.
Регистрация в iOS Developer Program. Для каждого приложения, в котором будет интегрирован механизм push-уведомлений, необходимо создать новый App ID и provisioning profile, а также SSL-сертификат для сервера. Эти действия выполняются на iOS Provisioning Portal.
Если хотите полностью выполнять примеры из этого руководства, вам необходимо создать provisioning profile и SSL-сертификат. Я в деталях объясню, как это сделать.
Сервер, подключенный к интернету. Push-уведомления всегда отправляются сервером. В процессе разработки вы можете использовать ваш собственный Мак в качестве сервера, но для релиза нужно что-то наподобие VPS (Virtual Private Server).
Для работы с push-уведомлениями дешёвого виртуального хостинга недостаточно. Вам необходимо запустить фоновое выполнение на сервере, установить SSL-сертификат, настроить исходящее TLS-соединение на определённых портах. Большинство провайдеров виртуального хостинга не позволят вам это сделать.
Что мы будем разбирать?
Мы разберем процесс управления вашим приложением в Apple Developer Center от его создания до публикации в магазине App Store. Мы будем говорить только о базовых вещах, таких, как разработка, тестирование и публикация, а также обсудим APNs (Push Notifications).
Отмечу тот факт, что далее я буду описывать принцип работы девцентра по состоянию на 31 марта 2021 года, поэтому если вы читаете эту статью позднее — все уже могло измениться.
Что нам понадобится?
Собственно, для работы нам нужно следующее:
Intermediate certificates
Некоторое время назад Apple внесла изменения в логику работы девцентра и своей системы сертификации, после чего на большинстве компьютеров пропала возможность делать сборки приложений, несмотря на наличие активных дев- и прод-сертификатов и актуальных профилей.
«Worldwide Developer Relations Certificate Authority»
. Он устанавливается автоматически с новыми версиями Xcode, но те, у кого Xcode уже был установлен ранее, просто должны были установить этот сертификат вручную, скачав его по прямой ссылке из секции Intermediate Certificates в девцентре Apple, после чего проблемы со сборками исчезали. Больше никакой смысловой нагрузки этот сертификат не несет.
Вкратце об itunes connect
Этот сервис предоставляет вам возможность управлять внутренним и внешним тестированием в TestFlight, а также выкладывать приложение в App Store. Рассмотрение этого процесса выходит за рамки данной статьи, упомяну лишь тот факт, что для корректной работы этому сервису необходимы сборки, созданные на базе профиля типа
Distribution — App Store
(для iOS либо tvOS). Другие типы профилей здесь не поддерживаются.
Идентификаторы (identifiers)
Данный раздел обеспечивает управление идентификаторами. Для вашего приложения в минимальном исполнении понадобится App ID, управление которыми доступно в одноименном подразделе.
В буквальном переводе «App ID» означает «идентификатор приложения», что полностью отражает его суть. Любое ваше приложение, которое вы хотите отлаживать на устройстве Apple, тестировать через TestFlight и/или публиковать в магазин App Store, должно обладать собственным уникальным именем, по которому его можно однозначно идентифицировать среди тысяч других приложений. При добавлении нового App ID вам будет предложено ввести несколько элементов:
- App ID Description. Имя вашего приложения. К примеру, если ваше приложение называется Mail Printer, то прямо так его и записываем в это текстовое поле.
- App ID Prefix. Префикс вашего приложения, он выдается вам автоматически и будет общим для конкретной команды Apple Team, где подключена и активна Apple Developer Program.
- App ID Suffix. Здесь нам понадобится выбрать Explicit App ID, чтобы указать бандл (bundle) приложения. Это идентификатор, обычно имеющий вид com.mycompany.myappname, где mycompany — имя вашей компании или вашего домена. Например, com.homecompany.MailPrinter. Обращаю ваше внимание, что точно такой же бандл должен быть выставлен в настройках таргета (Target) вашего приложения в Xcode (секция настроек General, поле Bundle Identifier).
- App Services. Здесь вам нужно отметить те сервисы, которые вы планируете использовать в вашем приложении. По умолчанию там отмечены только Game Center и In-App Purchase, их использование обязательно, удалить их нельзя. Остальные сервисы подключайте по мере необходимости.
После создания App ID вы можете использовать его для генерации любых типов профилей, об этом чуть позже.
Краткий обзор
Схема работы механизма push-уведомлений:
После установки приложения появится всплывающее сообщение с подтверждением принятия push-уведомлений.
- iOS запрашивает у сервера Apple Push Notification Service (APNS) токен девайса.
- Приложение получает токен девайса. Можно считать, что токен – это адрес для отправки push-уведомлений.
- Приложение отправляет токен девайса на ваш сервер.
- Когда произойдёт какое-либо событие для вашего приложения, сервер отправит push-уведомление в APNS.
- APNS отправит push-уведомление на девайс пользователя.
Когда пользователь получит push-уведомление, появится сообщение, и/или будет воспроизведён звуковой сигнал, и/или обновится бейдж на иконке приложения. Пользователь может открыть приложение из уведомления. Приложение получит контент push-уведомления и сможет обработать его.
Стоит ли по-прежнему использовать push-уведомления, если уже в iOS 4.0 появились локальные уведомления и мультизадачность? Ещё бы!
Локальные уведомления — это ограниченные по времени события. Только VOIP-приложения, навигация и фоновое воспроизведения звука обладают возможностью неограниченного фонового выполнения. Если необходимо уведомить пользователей приложения (пока оно закрыто) о каком-либо внешнем событии, вы всё ещё должны использовать push-уведомления.
В этом руководстве будет детально описана работа системы push-уведомлений и как её интегрировать в своё приложение.
Кратко о главном
В Apple Developer Center с незапамятных времен применяется довольно мудреная система сертификации ваших приложений на каждом из ключевых этапов — разработка, тестирование и публикация.
Зачастую при первом погружении в эту систему у начинающих (и не только) разработчиков возникают серьезные проблемы с пониманием того, как функционирует Apple Developer Center (будем называть его «девцентр» для простоты). В результате, мне в процессе профессиональной деятельности не раз приходилось наблюдать на новых местах работы огромные свалки из профилей и сертификатов в девцентре, в результате чего приходилось приступать к «разбору завалов».
При этом, в сети довольно не такой большой выбор материалов на эту тему. Конечно, в официальной документации Apple все хорошо структурировано и очень подробно описано, но зачастую просто не хватает времени на изучение такого количества материала.
Как правило, хочется быстро понять, что именно и в каком порядке нужно сделать для корректной работы приложения на этапах разработки, тестирования и при публикации его в магазин App Store. В русском же сообществе подобных материалов, собранных в одном месте и в удобном доступе, я не видел вовсе, поэтому и решил написать эту статью. Для всех интересующихся — добро пожаловать под кат.
Обновить push-сертификат и сохранить текущее приложение app store
У меня есть приложение в app store, которое использует профиль подготовки iOS (дистрибутив), срок действия которого истек.
Этот профиль содержит Push-сертификат, срок действия которого также истек (и больше не отображается на портале).
Вопрос 1:
Есть ли способ воссоздать push-сертификат, а затем обновить профиль? (У меня все еще есть сертификат push (истек) на моем брелке)?
Вопрос 2:
Нужно ли повторно отправлять приложение в app store с помощью новый профиль, содержащий новый сертификат Push?
поскольку срок действия сертификата push истек, я, вероятно, не могу отправлять уведомления существующим пользователям приложения.
Ориентировка по разделам
В девцентре для полноценной работы с вашими приложениями нам понадобятся только два пункта:
Подготовка apple push notification ssl сертификата | heximal blog
Сегодня хотел бы записать на память один нетривиальный процесс, касающийся внедрения механизма Apple Push Notification Service, который осуществляет рассылку коротких сообщений на устройства пользователей приложений в AppStore. И хотел бы я записать последовательность действий, производимых при создании и установки SSL Push Certificate, без которого не будет работать серверная часть, рассылающая пуши. Также если останется место, напишу, как реализовать самый простецкий push-сервер на php. Сама функция Push Notification очень полезна для оповещения пользователей о новых событиях в системе. Такие монстры, как Skype, Google, WhatsApp используют технологию push, чтобы осуществлять вызов абонентов или уведомлять о новых сообщениях на манер, как это делает стандартное приложение PhoneApp.Есть множество сценариев реализации push-технологии в своем проекте, я остановлюсь на одной, которую не так давно реализовывал в проекте Первая Помощь. Предположим, что у нас есть приложение компании, которое содержит каталоги офисов и каталоги промо-материалов компании (акции, новости). При этом стоит задача оповещать всех подписчиков услуги Push об открытии новых офисов и проведении новых акций. Какая в данном случае оптимальная конфигурация? На мой взгляд, в серверной архитектуре должна быть отдельная сущность, реализующая модель данных для Push, сущность для хранения push-токенов подписчиков услуги, и процедура рассылки, собирающая все готовые к отправке Пуш-сообщения на устройства подписчиков. Эта процедура должна стоять на расписании, большую часть своего времени она будет простаивать, но нагрузку это создает минимальную.
И так, что понадобится?
Про то, что нужно иметь официальный сертификат и быть участником программы iOS Developer, я уж не говорю (если не знаете, попробуйте ознакомиться со следующим материалом: Лёд тронулся, или «Мой путь в AppStore»).
1. Необходимо иметь созданный App ID (кто не в курсе, как, имеется и на тот случай статейка Публикуем приложение в AppStore)
И так, у нас есть APP ID, нам нужно сконфигурировать SSL-сертификат для Push Notification. Для этого мы открываем наш iOS App на просмотр в своем девелоперском аккаунте.

В секции Push Notification ставим галку, если Push Notification для приложения находится в состоянии Disabled. Теперь мы видим два фрейма с сертификатами Development SSL Certificate и Production SSL Certificate. В чем разница? Девелопмент сертификат нужен в период разработки, продакшн уже после публикации. Важное замечание: тестировать пуш можно только на физическом устройстве — в симуляторе не будет работать.
2. Нажимаем Create Certificate сначала для Development SSL Certificate. Для продакшн сертификата последовательность действий будет 100% аналогичная. Попадаем на страницу «About creating a Certificate Signin Request (CSR)», где дается описание наших дальнейших действий.

Необходимо создать запрос на подпись сертификата. Делается это через стандартное приложение OS X, которая называется «Связка ключей» (Keychain). Запускаем ее, и сразу идем в меню Связка ключей -> Ассистент сертификации -> Запросить сертификат у бюро сертификации.

В появившемся окне нужно выбрать опцию «Сохранен на диске», email пользователя (здесь часто рекомендуют вводить емэйл apple-аккаунта, но я не уверен, что это критично), Общее имя — так будет называться ваши личный и открытый ключи шифрования.

Далее нажимаем Продолжить, выбираем место на диске, куда будет сохранен файл запроса. Возвращаемся в developer portal к странице «About creating a Certificate Signin Request (CSR)», нажимаем там Continue, на появившейся странице выбираем наш файл запроса и нажимаем Generate. Немного подумав система выдает ссылку на скачивание сгенерированного сертификата, что мы и делаем.

Система предлагает сохранить файл сертификата под именем aps_development.cer. Советую создать отдельную папку, куда сохранять все причастное. Встраивать его в свою связку ключей совсем не обязательно
3. Далее необходимо выгрузить личный ключ. Открываем Связку ключей, находим свой ключ, выбираем его и через меню выбираем Файл -> Экспортировать Объект.

Система попросит ввести ключевое слово — это пароль для доступа к приватному ключу, что даже если кто-то завладеет экспортированным ключом, он им не сможет воспользоваться. Запомните эту фразу, обозначим ее как pass1.

Система предложит сохранить ключ в файле с расширением .p12 (пусть будет KeyName.p12). При этом еще попросит ввести пароль к связке ключей.

4. Далее нужно сконвертировать сам сертификат и ключ в формат PEM (связка ключей выгружает объекты в формате DER). Не знаю, чем это обусловлено, только библиотека openssl, с помощью которой мы будем осуществлять взаимодействие с Apple Push Notification Service (apns) в php, гораздо охотнее работает с файлами с формате PEM. Реализация openssl присутствует в большинстве *nix-систем, по крайней мере в OS X и FreeBSD она идет в стандартной комплектации. Открываем окно терминала и делаем следующее.
при выполнении второй команды консоль попросит ввести ключевую фразу трижды. Первый раз нужно ввести ту ключевую фразу, которую вы вводили при экспорте ключа (pass1). Второй и третий раз — новая ключевая фраза, с которой будет сгенерирован PEM ключ. Будем условно ее называть pass2. Если сделать ее такой же, как pass1 ничего криминального не будет.
Дальше нужно будет склеить эти два файла.
и в итоге получаем файл apns-dev.pem, который в дальнейшем и будем эксплуатировать на сервере.
Кстати, тут же можно проверить, что ssl-сертификат выгрузился/сконвертировался корректно. В консоли набираем
если вы тестируете production сертификат, то вместо домена gateway.sandbox.push.apple.com нужно указывать gateway.push.apple.com
Если все ок, консоль выдаст много-много текста.
Далее переносимся на сервер, копируем сертификат apns-dev.pem и создаем рядом с ним php-скрипт, который будет осуществлять непосредственно рассылку Push-сообщений
function replace_unicode_escape_sequence($match){returnmb_convert_encoding(pack('H*',$match[1]),'UTF-8','UCS-2BE');} function send_ios_push($message){$sound='default';$development=true; $payload=array();$payload["aps"]=array('alert'=>$message["body"],'sound'=>$sound);$payload=json_encode($payload);$payload=preg_replace_callback('/\\u([0-9a-f]{4})/i','replace_unicode_escape_sequence',$payload); $apns_url=NULL;$apns_cert=NULL;$apns_port=2195; if($development){$apns_url='gateway.sandbox.push.apple.com';$apns_cert='apns-dev.pem';}else{$apns_url='gateway.push.apple.com';$apns_cert='apns-dev-prod.pem';} if(file_exists($apns_cert))echo("cert file existsn");elseecho("cert file not existsn");;$success=0;$stream_context=stream_context_create();stream_context_set_option($stream_context,'ssl','local_cert',$apns_cert);stream_context_set_option($stream_context,'ssl','passphrase','pass2'); $apns=stream_socket_client('ssl://'.$apns_url.':'.$apns_port,$error,$error_string,2, STREAM_CLIENT_CONNECT,$stream_context); $device_tokens=array("ae7c44342eceef645f3baf9f7e1eb2daf383f9341535c8dd5ef7276a29068e8d","8d509c28896865f8640f328f30f15721ed40e41593e40a51e77b91c5b6db17d6"); foreach($device_tokensas$device){$apns_message=chr(0).chr(0).chr(32).pack('H*',str_replace(' ','',$devices)).chr(0).chr(strlen($payload)).$payload;if(fwrite($apns,$apns_message)){$success ;echo("sentn");}else{echo("failed n");}}echo("fetch donen");socket_close($apns);fclose($apns);return$success;} send_ios_push('Hello world');
Здесь следует обратить внимание на следующие нюансы.
stream_context_set_option($stream_context, ‘ssl’, ‘passphrase’, ‘pass2’);
В этом месте необходимо прописать ключевую фразу pass2 (см. выше). Иначе openssl будет каждый раз просить ввести ее вручную.
$payload = preg_replace_callback(‘/\\u([0-9a-f]{4})/i’,
‘replace_unicode_escape_sequence’, $payload);
это делается для того, чтобы увеличить фактическую длину сообщения. Поскольку php функция json_encode преобразует все не-ASCII символы в unicode-сущности, что в 5 раз уменьшает и так не большую максимальную длину Push-сообщения (256 символов).
Конечно вся остальная бизнес-логика может быть другой, например, список push-токенов не в виде константного массива $device_tokens. Этот кусок кода чисто для напоминания принципов работы именно с openssl в php и отправкой push-сообщений.
Если все это получилось, нужно будет все то же самое проделать для Production сертификата, прежде чем публиковать приложение.
Понимание push-уведомлений
Они не надёжны!
Нет гарантий, что push-уведомления будут доставлены, даже если APNS примет их.
Как только ваш сервер сформировал push-уведомление, он безответно отправляет его в APNS. Нет способа узнать статус доставки уведомления конечному пользователю после отправки. Время доставки может варьироваться от нескольких секунд до получаса.
Кроме этого, у пользователей i-девайсов может не быть возможности получать push-уведомления всё время. Например, рядом нет Wi-Fi сети с доступом в интернет либо девайс может быть вообще выключен.
APNS будет пытаться доставить последнее отправленное уведомление, когда девайс станет доступен для приёма. Но эти попытки ограничены по времени. После тайм-аута push-уведомление будет потеряно навсегда!
Они могут быть дорогими! Добавить push-функционал в приложение довольно просто и недорого, если вы владеете данными. Однако если у вас много пользователей либо необходимо запрашивать данные, то затраты резко возрастают.
К примеру, вы без проблем сможете оповестить пользователей об изменении RSS-ленты, потому что вы контролируете ленту и знаете, когда будут внесены изменения — когда обновится контент на сайте — ваш сервер мгновенно отправит уведомление.
Но что если ваше приложение — это RSS-читалка, позволяющая пользователям вносить URL-адреса своих лент? В этом случае вам необходимо придумать механизм слежения за обновлением добавленных лент.
На практике это означает, что вашему серверу нужно постоянно проверять ленты на изменение. Если у вас много пользователей, то возможно, придётся установить дополнительные сервера для обработки всех процессов и поддержки стабильной пропускной способности.
Ладно, хватит теории. Настало время изучить процесс реализации всех этих push-вещей. Но до того, как приступать к самому «вкусному» — программированию! — нужно выполнить несколько скучных настроек на iOS Provisioning Portal. Что ж, давайте сделаем их настолько быстро, насколько это возможно.
Простенькое приложение
Предыдущие действия не были по-настоящему захватывающими, но они обязательны для выполнения. Я хотел в деталях показать, как сгенерировать сертификат, потому что такие вещи разработчик делает не каждый день, а без них push-уведомления работать не будут.
Сейчас мы создадим простое приложение, которое будет принимать push-уведомления.
Откройте Xcode и создайте новый проект. В ассистенте выберите «Single View Application» и перейдите к следующему шагу.
Я заполнил поля следующим образом:
После создания проекта, откройте PCAppDelegate.m. Измените метод didFinishLaunchingWithOptions следующим образом:
Профили (provisioning profiles)
Дословно название этого раздела переводится как «Профили обеспечения». Чуть более развернуто я бы описал понятие «профиль» как «Специальный файл, обеспечивающий доступ к некоторой функциональности в конкретной сборке вашего приложения». В данном разделе девцентра вы можете управлять вашими профилями, обеспечивая себе возможность выпускать сборки приложения для различных целей, то есть «профилировать» его. По сути, профиль является результатом объединения двух (иногда трех) компонентов:
На выходе как раз и получаем профиль для выпуска сборок с определенными целями. Давайте рассмотрим разновидности профилей.
Профили типа «development»
Это профиль для разработки, то есть его основное назначение — отладка вашего приложения на конкретных устройствах через Xcode с прямым подключением устройства проводом к вашему Mac. Дев-профили представлены двумя видами:
Профили типа «distribution»
Эти профили используются для выпуска сборок вашего приложения для различных целей. Продакшн-профили представлены четырьмя видами:
- App Store. Используется для тестирования (как внутреннего, так и внешнего) в TestFlight, а также для выпуска приложения в App Store.
- tvOS App Store. Аналогично предыдущему, только для tvOS.
- Ad Hoc. Требует указания перечня разрешенных устройств из раздела Devices.
Используется, если вы хотите выпустить сборку, которую можно будет поставить в режиме «Production», но только на некоторых устройствах. Реальная ситуация, когда это может понадобится, например, следующая. Вы разрабатываете приложение, а в процессе работы заказчик попросил у вас «дать ему пощупать приложение» на своем Apple-устройстве. В iTunes Connect для активации внешнего тестирования вы еще выходить не готовы, но просьбу заказчика нужно выполнять — вот тут как раз и пригодится Ad Hoc-профиль, сгенерированный на базе прод-сертификата App Store & Ad Hoc Production Certificate. Важный момент: в моем случае часто возникали проблемы при экспорте сборок подобным способом, если в Xcode не был также установлен и Development-сертификат. Ошибки были разного рода, от невозможности подписать сборку до абсурдного «App ID is not available», хотя это фактически не так (замена на другой бандл ничего не давала). Поэтому, по моему предположению, для удачного экспорта Ad Hoc-сборок необходимо, чтобы, помимо Ad Hoc-профиля, был также установлен и дев-сертификат с соответствующим профилем. - tvOS Ad Hoc. Аналогично предыдущему, только для tvOS.
Резюмируем
По сути, при получении доступа к девцентру с активной Apple Developer Program ваш алгоритм действий должен сводиться к следующему:
Сертификаты (certificates)
Этот раздел дает доступ к управлению сертификатами, которыми обладает ваша учетная запись Apple ID. Каждый из этапов, которые вы будете проходить, будь то разработка, тестирование или публикация, включая все значимые составляющие экосистемы Apple вроде Push Notifications, требует обязательного наличия актуального (действующего, Active) сертификата.
Теперь разберем типы сертификатов.
Сертификаты типа «development»
В первую очередь, нужно знать, что девелоперский сертификат всегда привязывается
к одной конкретной машине
. Поэтому для отладки на вашем Mac вам понадобится доступ к этому сертификату. Тут есть варианты. Например, если, вы устроились на работу iOS-программистом, и в ваши задачи входит отладка на устройствах (как правило, так и есть), то есть два пути решения (какой из них выбирать — зависит от вас и условий работы в вашей компании):
Создание provisioning profile
Зайдите на Provisioning Portal. Перейдите по ссылке «Provisioning» и нажмите на кнопку «New Profile».
Я заполнил поля следующим образом:
Этот процесс никак не отличается от генерации любого другого provisioning profile. Мы создаём новый profile, потому что каждому приложению, поддерживающему механизм push-уведомлений, необходим свой собственный profile, который связан с определённым App ID.
Терминология
Давайте подробно разберем понятия, лежащие в основе функционирования девцентра Apple.
Устройства (devices)
В этом разделе размещено управление всеми устройствами Apple, которые вы можете использовать в рамках вашей Apple Developer Program. Есть ограничение, максимум 100 зарегистрированных девайсов одного типа (iPhone, iPad и так далее) на одну учетную запись в год, обычно этого более чем достаточно.
🚧best practices
When recreating new profiles make sure to enter a unique name in the “Provisioning Profile Name:” field.
Example, if creating an Ad-Hoc Provisioning Profile to test push notifications with a Production Push Certificate .p12 file. Use the format AppName_AdHoc so you know the app and type it is.
🚧previous certificate revokation
Previous p12 Push Certificates for this bundle id will be revoked and cannot be used once you generate a new certificate with this method.
