Правильная последовательность, чтобы получить регистрационный токен для push-уведомления GCM на iOS? Неужели GCM ненадежна?
Привет, я следил за учебником по использованию GCM на iOS. Он работает с перерывами (что означает, что все сертификаты, разрешения и все в порядке). Однако в последнее время я неоднократно получаю два сообщения об ошибках:
GCM | GCM registration is not ready with auth credentials
.
Кроме того, повторное подключение к GCM не выполняется:
Error Domain=com.google.gcm Code=501 "(null)"
Это относится, в частности, к устройству, не получающему идентификатор регистрации GCM. Кто-нибудь еще сталкивается с этими проблемами чаще в последнее время? Или это потому, что я вызываю GCM API в неправильной последовательности (особенно методы connectWithHandler:
, startWithConfig:
и tokenWithAuthorizedEntity
)? Я подозреваю, что причина в том, что последний, поскольку я получаю идентификатор GCM после некоторой задержки.
Я не всегда получаю идентификатор GCM. Когда я не получаю один, я обычно должен запускать приложение один или два раза через Xcode. (Или путем принудительного закрытия приложения). Очевидно, что это не то, что мои пользователи должны делать.
Это последовательность вызовов API GCM:
- Устройство получает токен APNS
- Затем я звоню
tokenWithAuthorizedEntity:
, используя токен APNS
- ^ Это обычно
приводит к одной из двух упомянутых выше ошибок.
- Всякий раз, когда я
на самом деле нужен токен GCM, я принудительно обновляю токен GCM
вызывая
tokenWithAuthorizedEntity
снова.
Кроме того, у меня есть вызов connectWithHandler:
, написанный внутри моего метода applicationDidBecomeActive:
.
Несколько вопросов:
- Требуется ли вызов
connectWithHandler:
в applicationDidBecomeActive:
, если меня интересует только получение push-сообщений GCM, а не отправка их вверх по течению?
- Если ответ на (1) - да, в обработчике завершения этого метода, если возникает ошибка, и у меня нет маркера GCM в этой точке, я должен попытаться снова получить токен? (т.е. вызов
tokenWithAuthorizedEntity
?)
- Когда следует вызывать
startWithConfig
? Перед тем, как получить токен GCM или после?
EDIT: Ограниченное тестирование показало, что работает следующее:
- Сначала введите идентификатор GGLInstance (т.е. вызов
getIDWithHandler:
)
- Если вышеуказанный идентификатор GGLInstance был получен без какой-либо ошибки, попросите маркер GCM (т.е. вызов
tokenWithAuthorizedEntity:
)
- Выполнение этого обычно дает следующую ошибку, но, по крайней мере, за короткое время (~ 3-10 секунд), токен получен:
Невозможно найти маркер в кеше. Error Domain = com.google.iid Код = -25300 "(Нуль)"
Ответы
Ответ 1
Является ли вызов connectWithHandler: in applicationDidBecomeActive: необходимо, если меня интересуют только сообщения GCM push и не отправлять их вверх по течению?
Да, connectWithHandler необходимо, несмотря на то, что его основной целью является соединение с конечной точкой GCM.
Если ответ на (1) да, в обработчике завершения этого метода, если возникает ошибка, и у меня нет токена GCM в этот момент, если Я пытаюсь снова получить токен? (то есть вызов tokenWithAuthorizedEntity?)
Итак, как это работает, вы проверяете ошибки во время запроса самого токена и повторите попытку с экспоненциальным отклонением, если запрос завершился с ошибкой. Подробнее здесь. Также читайте примечание здесь. Теперь, если вы все еще хотите повторно вызвать GGLInstanceIDTokenHandler
в любой момент, вы также должны реализовать deleteTokenWithAuthorizedEntity
перед тем, как получить новый токен.
Когда следует вызывать startWithConfig? Перед тем, как получить токен GCM или после?
В AppDelegate.m
вы должны вызвать экземпляр GGLInstanceID
shared с использованием метода startWithConfig
. По существу в классе GGLINstanceID.h
он должен сначала получить идентификатор экземпляра; затем авторизуйте проект как Уполномоченное лицо, а затем получите токен регистрации через службу iid. См. Подробную реализацию для GGLINstanceID.h
class здесь.
Надеюсь, что это поможет в помощи!
EDIT
Отвечает ли этот вопрос на ваш вопрос? Суть его заключается в том, чтобы идентификатор Bundle для вашей цели был таким же, как BUNDLE_ID в файле info.plist.
Надеюсь, это разрешит ошибку, если не опубликует, что произошло, когда вы ее протестируете, и мы можем идти оттуда.:)
Ответ 2
Попробуйте переместить блок connectWithHandler в метод didFinishLaunchingWithOptions после того, как вы получите блок gcmConfig. (для официального примера, после [END start_gcm_service])