正确的序列获取注册令牌在iOS上的GCM推送通知? GCM不可靠吗?

嗨,我已经按照教程在iOS上使用GCM。 它一直在间歇工作(这意味着所有的证书,权限和东西都可以)。 不过到最近,我一直在收到这两条错误消息:

GCM | GCM registration is not ready with auth credentials GCM | GCM registration is not ready with auth credentials

此外,重新连接到GCM失败:

Error Domain=com.google.gcm Code=501 "(null)"

这部分与设备没有获得GCM注册ID有关。 有没有其他人更频繁地遇到这些问题? 或者是因为我以不正确的顺序调用GCM API(尤其是connectWithHandler:startWithConfig:tokenWithAuthorizedEntity方法)? 我怀疑原因是后者,因为我经过一段时间才得到GCM ID。

我并不总是收到一个GCM ID。 当我没有收到一个,我通常必须通过Xcode运行一次或两次的应用程序。 (或通过强制closures应用程序)。 显然这不是我的用户应该做的事情。

这是我的GCM API调用的序列:

  1. 设备获取APNS令牌
  2. 然后我调用tokenWithAuthorizedEntity:通过使用我的APNS令牌
  3. ^这通常会导致上面提到的那两个错误之一。
  4. 每当我真的需要一个GCM令牌时,我通过再次调用tokenWithAuthorizedEntity强制重新获取GCM令牌。

另外,我connectWithHandler:我的applicationDidBecomeActive:方法中写入了connectWithHandler: call。

几个问题:

  1. connectWithHandler:的调用connectWithHandler:applicationDidBecomeActive:必要时,如果我只是有兴趣接收GCM推送消息,而不是向上游发送?
  2. 如果对(1)的回答是肯定的,则在该方法的完成处理程序中,如果发生错误,并且我没有GCM标记,那么我应该尝试再次获取标记吗? (即调用tokenWithAuthorizedEntity ?)
  3. 什么时候应该调用startWithConfig ? 在获取GCM令牌之前或之后?

编辑:有限的testing显示,以下似乎工作:

  1. 首先获取GGLInstance ID(即调用getIDWithHandler:
  2. 如果上面的GGLInstance ID没有收到任何错误,请求一个GCM令牌(即调用tokenWithAuthorizedEntity:
  3. 这样做通常会导致以下错误,但至less在短时间内(〜3-10秒) 收到令牌:

无法在caching中find令牌Error Domain = com.google.iid Code = -25300“(null)”

是connectWithHandler的调用:在applicationDidBecomeActive:必要时,如果我只是有兴趣接收GCM推送消息,而不是向上游发送?

是的, connectWithHandler是必要的,不pipe它的主要目的是与GCM端点连接。

如果对(1)的回答是肯定的,则在该方法的完成处理程序中,如果发生错误,并且我没有GCM标记,那么我应该尝试再次获取标记吗? (即调用tokenWithAuthorizedEntity?)

所以它应该工作的方式是在请求令牌本身时检查错误,如果请求失败,则以指数退避(back-off)方式重试。 更多信息在这里 。 另外,请阅读这里的说明。 现在,如果您仍想在任何时候重新调用GGLInstanceIDTokenHandlerdeleteTokenWithAuthorizedEntity在获取新令牌之前,还应该实现deleteTokenWithAuthorizedEntity

什么时候应该调用startWithConfig? 在获取GCM令牌之前或之后?

在您的AppDelegate.m您应该使用startWithConfig方法调用GGLInstanceID共享实例。 基本上在GGLINstanceID.h类中,它应该首先获得一个实例ID; 然后授权项目为授权实体,然后通过iid服务获得注册令牌。 在这里查看GGLInstanceID.h类的详细实现。

希望这个答案帮助!

编辑

这是否回答你的问题? 要点是,确保你的目标的Bundle Identifier与info.plist文件中的BUNDLE_ID相同。

希望这可以解决这个错误,如果不是在你testing的时候发布了什么,我们可以从那里发布。 🙂

获取gcmConfig块后,尝试将connectWithHandler块移动到didFinishLaunchingWithOptions方法(对于官方示例,在[END start_gcm_service]之后)