Как стать автором
Обновить

Push уведомления в приложениях для iOS

Время на прочтение3 мин
Количество просмотров12K
Добрый день, Хабражитель.
Все наверное в курсе, что в iOS существует такой полезный сервис как Push уведомления. Я тоже был в курсе, но пока не столкнулся с его реальным использованием, даже не знал, что с ним есть так много нюансов. В этом топике вы узнаете два аспекта об этом сервисе: что нужно делать в xCode, и как отсылать сами пуш сообщения через php сервер.
Под катом описано то, как все это работает.

Столкнулся я с Push совсем недавно, когда разрабатывал свое новое приложение — Family Expenses. Там я собирался применить Push для уведомления пользователя о запросе синхронизации.

Push-уведомления бывают двух видов: локальные и удаленные. Локальные в этой статье рассматривать не будем. У них достаточно простой механизм реализации и детально описан в референсах.

Механизм удаленного Push уведомления выглядит следующим образом.

  1. При старте приложения вызывается метод didRegisterForRemoteNotificationsWithDeviceToken который, если есть подключение к интернет возвращает 64 символьную строку Token. С этой стройкой есть нюанс: она почему-то приходит с символами «<» и «>» в начале и конце и пробелами в средине. Поэтому стоит почистить строку от этих символов.
  2. Токен необходимо отправить на ваш сервер, который хранит его. По сути он является уникальным адресом приложения и девайса. Через него потом и ведётся отправка Push уведомления. В коде ниже как раз представлен механизм описанный в пунктах 1 и 2.

    - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken  
    {  
        NSMutableString *tokenString = [NSMutableString stringWithString:  
                                        [[deviceToken description] uppercaseString]];  
        [tokenString replaceOccurrencesOfString:@"<"  
                                     withString:@""  
                                        options:0  
                                          range:NSMakeRange(0, tokenString.length)];  
        [tokenString replaceOccurrencesOfString:@">"  
                                     withString:@""  
                                        options:0  
                                          range:NSMakeRange(0, tokenString.length)];
        [tokenString replaceOccurrencesOfString:@" "  
                                     withString:@""  
                                        options:0  
                                          range:NSMakeRange(0, tokenString.length)];     
        NSLog(@"Token: %@", tokenString);  
        
        if (tokenString) {
            [[NSUserDefaults standardUserDefaults] setObject:tokenString forKey:@"token"];
        }
        
    
        NSString *urlFormat = @"http://your.domain.com/regDevice.php?deviceToken=%@";  
        NSURL *registrationURL = [NSURL URLWithString:[NSString stringWithFormat:  
                                                       urlFormat, tokenString];  
     
        NSMutableURLRequest *registrationRequest = [[NSMutableURLRequest alloc]  
                                                    initWithURL:registrationURL];  
        [registrationRequest setHTTPMethod:@"PUT"];  
        
     
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:registrationRequest  
                                                                    delegate:self];  
        [connection start];  
        
        
        [registrationRequest release];
       
    }   
    

    На стороне приложения это практически все, не считая механизма обработки входящего сообщения.
  3. По мере необходимости наш сервер инициализирует отправку Push уведомления, адресом получателя в котором является Токен. Для этого на сервере должен быть Push сертификат который можно получить developer.apple.com в разделе Provisioning Portal -> App IDs -> Configure напротив вашего App ID. Детально описывать этот процесс не буду, потому что там же есть пошаговая инструкция как создать сертификат.
    Но тот сертификат для нашего сервера не подходит полностью. Его необходимо ещё обработать и обединить с вашим сертификатом разработчика.
    Детальную пошаговую инструкцию можно подсмотреть здесь.


Для отправки сообщения на сервере, в нашем случае хостинг с PHP, необходимо установить сертификат, который сгенерирован по инструкции в ссылке выше.
На своем сервере я использовал ApnsPHP — это класс с открытым исходным кодом для взаимодействия с Apple Push Notification service.
Все очень просто и удобно. Самое главное – заводится с пол-пинка. code.google.com/p/apns-php
Там же есть и пример проекта для xCode с механизмом обработки входящих Push сообщений.

Если в общем – то это практически все.

Теперь нюансы, с которыми я столкнулся.
Для отправки сообщений в Apple предусмотрели два сервера:
ssl://gateway.push.apple.com:2195
ssl://gateway.sandbox.push.apple.com:2195

Первый используется для завершенных продуктов, а второй для тестирования, «песочница».
Если вы тестируете приложение в режиме Debug и с Developer provision profile – тогда при тестировании на сервере используйте sandbox. Если же вы делаете Ad Hoc релиз, то есть подписываете приложение уже сертификатом для дистрибуции – тогда sandbox уже работать не будет. Пишу об этом, потому что сам долго не мог понять, почему не работает.
Ещё есть специальный механизм для чистки базы токенов от адресов, которые уже не действительны. Например, если приложение было удалено с девайса.
Для этого можно использовать ApnsPHP там тоже есть для этого механизмы.

Надеюсь, что достаточно просто описал механизм.
UPD.
Только что эксперементировал. Оказалось, что Токен один для конкретного девайса, и или, может быть для одного разработчика. Потому что с разными bundle ID у меня выдает один и тот же токен. А вот какому приложению отсылать — это определяет сертификат, который на сервере.
Теги:
Хабы:
+23
Комментарии44

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн