Как пробудить приложение в iOS: по расписанию и не очень


7627ed6fede049cb981ef2532166f8ee.jpgПуш-уведомления — хороший способ взаимодействия с пользователями, их вовлечения и возврата в приложения (кто хоть раз не просыпался ночью от не вовремя доставленного уведомления?). Однако есть у пушей и еще одна интересная функция, о которой не все знают.

Представьте, что ваш мессенджер, так любимый пользователем, отправляется в фоновый режим и там «засыпает». Как ему принять звонок, будучи не подключенным к серверу? Ответ как раз и заключается в пуше — сообщение «будит» приложение, оно переходит в активный режим и уже может принять звонок.

В iOS существует несколько способов пробудить приложение и передать ему контроль над происходящим.

Есть UILocalNotification — отложенные уведомления, привязанные к определенному моменту в будущем. Поскольку мы не знаем, когда поступит звонок, работать с UILocalNotification для организации телеконференций невозможно.

Есть извлечение данных в фоновом режиме (Background fetch), описываемое UIBackgroudnModes. Оно также привязывается ко времени и может будить приложение для скачивания и обновления данных в нужный момент времени. Так как мы не можем указать точное время звонка, фоновое пробуждение работать со звонками тоже не может.

Будить приложение можно удаленными уведомлениями. Если вы делаете свой проект, то включается эта возможность в закладке проекта «Capabilities» в Xcode, там есть раздел «Background Modes» и опция «Remote notifications» (также можно включить ключ UIBackgroundModes со значением «remote-notification» в Info.plist).

6074ac54f6d2424a858bdeb154b76d7a.png

В самом уведомлении необходимо сделать ключ content-available со значением 1:

{
	"aps" : {
    	"content-available" : 1
	},
	"content-id" : 42
}

только тогда приложение проснется (или запустится) и вызовет метод application: didReceiveRemoteNotification: fetchCompletionHandler. Как раз в нем вы можете уже реализовать нужный функционал.
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
     fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
	NSLog(@"Remote Notification userInfo is %@", userInfo);
 
	NSNumber *contentID = userInfo[@"content-id"];
	// Do something with the content ID
	completionHandler(UIBackgroundFetchResultNewData);
}

В этом обработчике вы можете загрузить нужный контент, подключиться к серверу и, например, проверить наличие вызовов (для работы с пушами рекомендую статью «Уведомления в iOS 10» от e-Legion, в котором рассмотрены вопросы более подробно).

Apple для VoIP приложений рекомендует пробуждение как раз через UIBackgroundModes, но, конечно, не по времени, а по прослушиванию входящего трафика. Мессенджер в фоне мониторит определенный сокет и при появлении в нем трафика вызывает обработчик, запускающий нужные процедуры.

Пуши Voximplant для iOS основаны как раз на VoIP варианте. Для работы нужно:

1. Подписаться на уведомления при старте приложения:

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

2. Обработать входящие сообщения и передать входящий токен в SDK:
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {
	// 'self.sdk' is an instance of the 'VoxImplantSDK'
	[self.sdk registerPushNotificationsToken:credentials.token];
}

3. После получения пуша, если приложение не подключено к облаку Voximplant, нужно переподключиться и получить входящий звонок:
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type {
	NSDictionary* custom = [[payload.dictionaryPayload objectForKey:@"aps"] objectForKey:@"voximplant"];
	if (custom) {
    	// This call notifies Voximplant cloud that notification is successfully received.
    	[self.sdk handlePushNotification:payload.dictionaryPayload];
 	}
}

Пуши — мощное средство удаленного общения с приложением, а не просто средство показывать пользователю информацию о том, что чужаки разграбили его ферму. Это возможность получать информацию в фоновом режиме, «включать» приложение по звонку, обновлять пользовательские данные. В конечном счете все это — средства удобной работы и вовлечения пользователей в работу приложения.

Комментарии (3)

  • 15 марта 2017 в 12:14

    0

    Разве публикация картинки без указания авторства не нарушает лицензию CC?
    Автор David Revoy.
  • 15 марта 2017 в 12:16

    0

    Так если у вас VOIP приложение, зачем вам пуши? Слушайте себе сокет и стартуйте сервис по запросу извне.
    • 15 марта 2017 в 12:27

      0

      В iOS это больше не работает

© Habrahabr.ru