Внедрение PushKit и тестирование в процессе разработки

Я хотел бы реализовать сервис PushKit в своем приложении (приложение Voip), но у меня есть следующие сомнения: я вижу, что я могу генерировать только производственный сертификат voip, он работает, если я пытаюсь проверить службу уведомления voip push для разработки устройства

Это мой тест внедрения:

С помощью этой 3 строки кода я могу получить токен на обратном вызове didUpdatePushCredentials, который я использую для сохранения на моем сервере.

PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

На стороне сервера я генерирую "обычное" push-сообщение полезной нагрузки только с предупреждающим текстом, и я отправил токен voip, сохраненный на моем сервере.

Я использую обратный вызов с журналом отладки, но они никогда не вызываются!

- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type {

          NSLog(@"didInvalidatePushTokenForType");

}

-(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {

          NSLog(@"didReceiveIncomingPushWithPayload: %@", payload.description);

}

-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
     if([credentials.token length] == 0) {
           NSLog(@"voip token NULL");

          return;
     }

      NSLog(@"didUpdatePushCredentials: %@ - Type: %@", credentials.token, type);

}

Если я попытаюсь создать push-уведомление с моего сервера, чтобы отправить ранее загруженный токен устройства, я никогда не уведомляюсь о обратном вызове didReceiveIncomingPushWithPayload, но с сервера я получаю сообщение 200 ok (сообщение было успешно отправлено)

Ответ 1

На всякий случай кто-то заинтересован в тестировании push-push-уведомлений с Pushkit, здесь я оставил небольшую процедуру, которую я успешно выполнил:

1. Создайте, если у вас его уже нет, CSR с доступом к цепочке ключей и сохраните свой CSR локально.

2 - зайдите в Apple Developer и получите доступ к сертификатам, идентификаторам и профилям доступа. В центре участника.

  • Внутренние идентификаторы- > Идентификаторы приложений Создайте один новый идентификатор приложения
  • Внутренние устройства- > Все Добавить устройства UDID, которые вы хотите использовать для тестирования push-нажатий
  • Внутренние сертификаты- > Все Создать новый сертификат на производство: сертификат служб VoIP. Выберите ранее созданный идентификатор приложения для вашего сертификата обслуживания VoIP. Выберите ранее созданный CSR (запрос подписи сертификата) и после создания загрузите новый файл voip_services.cer

После загрузки дважды щелкните по voip_services.cer, чтобы открыть приложение Keychain Access и экспортировать закрытый ключ для сгенерированного сертификата: щелкните правой кнопкой мыши Экспорт файла certificate.p12.. p >

Сохраните voip_services.cer и файл сертификата .p12 в папке, чтобы создать генератор push-уведомлений сервера

Наконец, перейдите на веб-сайт Apple Developer снова и внутри Provisioning Profiles- > Distribution создайте новый профиль Ad-Hoc распространения, включая на нем все UDID-устройства, которые вы хотите использовать для тестирования push-push. Загрузите этот профиль и перетащите его на свой xcode, чтобы использовать его в своем приложении.

Теперь давайте создадим приложение iOS, которое получит уведомления о push-push:

  • Создайте новое приложение Single View из меню нового проекта Xcode.
  • Заполните свой идентификатор пакета в соответствии с созданным идентификатором приложения в предыдущем разделе.
  • Добавить PushKit.framework в общие → Связанные структуры и библиотеки.
  • В возможностях включить фоновый режим и выбрать опцию Voice over IP.
  • В настройках сборки → Подпись кодов выберите профиль предварительной настройки, который вы загрузили ранее, и выберите Распространение как идентификатор подписи кода.

Давайте добавим в приложение код Pasquale, добавленный в его вопрос:

В заголовке контроллера корневого представления ( ViewController.h ) импорт для PushKit.framework:

#import <PushKit/PushKit.h>

Добавить делегат для реализации его функций:

@interface ViewController : UIViewController <PKPushRegistryDelegate>

Добавить в viewDidLoad функцию вашего контроллера корневого представления (ViewController.m) push registration:

- (void)viewDidLoad {
    [super viewDidLoad];

    PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
    pushRegistry.delegate = self;
    pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}

Реализация требуемых функций делегата:

- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
    if([credentials.token length] == 0) {
        NSLog(@"voip token NULL");
        return;
    }

    NSLog(@"PushCredentials: %@", credentials.token);
}

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
    NSLog(@"didReceiveIncomingPushWithPayload");
}

Как только все будет компилироваться и одобрено, заархивируйте свой проект и экспортируйте файл ipa, чтобы установить его на тестовые устройства (вы можете использовать, например, Testflight для выполнения задания).

Выполните его и получите из журналов PushCredentials, которые мы будем использовать для отправки push.

Теперь перейдем к серверной части (я следовал этому великому руководству учебники по raywenderlich):

Вернитесь в папку, где вы разместили три файла:

  • voip_services.cer
  • certificate.p12

1 - Откройте терминал и создайте файл pem из файла сертификата:

#openssl x509 -in voip_services.cer -inform der -out PushVoipCert.pem

2 - Создайте файл pem из экспортированного файла закрытого ключа:

#openssl pkcs12 -nocerts -out PushVoipKey.pem -in certificate.p12

3 - Присоедините оба файла pem в одном:

#cat PushVoipCert.pem PushVoipKey.pem > ck.pem

Чтобы отправить push, вы можете использовать Pusher из raywenderlich tutorials или с помощью простого php script:

<?php

// Put your device token here (without spaces):
$deviceToken = '0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78';

// Put your private key passphrase here:
$passphrase = 'pushchat';

// Put your alert message here:
$message = 'My first push notification!';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
    'alert' => $message,
    'sound' => 'default'
    );

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
    echo 'Message not delivered' . PHP_EOL;
else
    echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);

вы должны изменить в script:

  • $deviceToken, добавив ваши PushCredentials (из журналов приложений)
  • $passphrase парольной фразой, добавленной вами на шаге 2 при создании PushVoipKey.pem

Что это. Выполнить php script:

#php simplePushScript.php

и вы должны получить свое уведомление об удалении voip (вы должны увидеть журнал приложений: "didReceiveIncomingPushWithPayload" )

После этого теста я задавался вопросом, как получить стандартные push-уведомления через платформу pushkit, но, к сожалению, у меня нет ответа, так как при регистрации типа push я не смог найти какой-либо другой PKPushType, но PKPushTypeVoIP...

pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

Это все! Спасибо за чтение!

Ответ 2

Сегодня я подробно изучил это. Мне тоже было интересно, как использовать сгенерированный токен в сборке для разработки, когда Apple только позволяет нам создавать производственный сертификат push push.

На сервере вам нужно отправить производственный push на gateway.push.apple.com, а push файл для разработки/песочницы - на gateway.sandbox.push.apple.com. Я смог генерировать и получать VoIP-нажатия на сборку разработки моего приложения, используя производственный сертификат VoIP на gateway.sandbox.push.apple.com. Я еще не пробовал, но предположим, что он также будет работать на специальной или производственной сборке и с помощью gateway.push.apple.com.

Также обратите внимание, что push-уведомления вообще не работают в симуляторе.

Ответ 3

Вам также нужно включить удаленные уведомления, даже если вы их не используете:

  • внутри вашего идентификатора идентификатора приложения на портале разработчика
  • воссоздать профили Provisioning Development
  • hit Скачать все в XCode → Настройки... → Учетные записи → ваша учетная запись
  • включить удаленные уведомления в возможностях → фоновый режим

Сделано это, вы получите обратный вызов делегата как в Debug, так и в Release.