让 GCM 在后台为 iOS 设备工作 [英] Making GCM work for iOS device in the background

查看:29
本文介绍了让 GCM 在后台为 iOS 设备工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 GCM 用于 IOS 和 Android 客户端.当应用程序在前台时,它似乎与 IOS 一起工作正常,但是,当应用程序在后台时,通知中心不会收到消息,并且 didReceiveRemoteNotification with completionHandler 不会被调用.

I'm trying to use GCM for IOS and Android clients. It seems to work fine with IOS when app is in the foreground, however, when the app is in the background, the notification center doesn't receive the message and didReceiveRemoteNotification with completionHandler doesn't get called.

我发现问题是从 GCM 到 APNS 的消息格式错误.也就是说,这就是它的样子:

I identified a problem as a wrongly formatted message from GCM to APNS. Namely, that's how it looks:


[message: New message, collapse_key: do_not_collapse, from: **************]

而 IOS 推送通知应该在通知中有 aps 键,对吗?以及 content-available 设置为 1.例如:

While, the IOS push notifications should have aps key in the notification, am I right ? As well as content-available set to 1. For example:

{aps":{内容可用":1},数据ID":345}

{ "aps" : { "content-available" : 1 }, "data-id" : 345 }

顺便说一下,反正前台app收到消息,只是后台有问题.关于我应该如何解决问题,让 GCM 同时适用于 ios 和 android 的任何建议?

By the way, in the foreground app receives the message anyway, the problem is only with the background. Any advice on how should I approach a problem, to make GCM work for both ios and android?

更新:这是我在网上找到的:

UPDATE: That is what I found on the net:

关于实际通信,只要应用程序在 iOS 设备的后台,GCM 使用 APNS 发送消息,应用程序的行为类似于使用 Apple 的通知系统.但是当应用处于活动状态时,GCM 会直接与应用通信

Regarding actual communication, as long as the application is in the background on an iOS device, GCM uses APNS to send messages, the application behaving similarly as using Apple’s notification system. But when the app is active, GCM communicates directly with the app

所以我在前台模式下收到的消息:

So the message I received in the foreground mode:

[消息:新消息,collapse_key:do_not_collapse,来自:**************]

[message: New message, collapse_key: do_not_collapse, from: **************]

是GCM的直接消息(APNS根本没有参与这件事).所以问题是:APNS 是否会重新格式化 GCM 发送给它的内容以符合 ios 通知格式?如果是这样,我怎么知道 APNS 实际上做了什么,以及它是否以不同的格式向我发送通知?有什么办法可以查看来自 APNS 的传入数据的日志吗?

Was the direct message from GCM(APNS did not participate in this affair at all). So the question is: does APNS reformat what GCM sends to it to adhere to ios notifications format? If so how do I know that APNS actually does something and whether it sends me a notification in different format ? Is there any way to view logs of incoming data from APNS ?

更新:好的,我设法更改了消息的结构,现在在前台模式下我收到以下消息:

UPDATE: Okay, I managed to change the structure of the message and now in the foreground mode I receive the following message:

收到通知:["aps": {"alert":"Simple message","content-available":1},collapse_key: do_not_collapse, from: ****************]

Notification received: ["aps": {"alert":"Simple message","content-available":1}, collapse_key: do_not_collapse, from: **************]

现在好像格式化好了,但是app在后台还是没有反应.didReceiveRemoteNotifification completionHandler 没有被调用!我应该寻找什么以及问题出在哪里?方括号是否会成为推送通知的问题?更准确地说,ios 不会发布来自该传入通知的任何警报/徽章/横幅.

Now it seems to be well formatted, but there is still no reaction when the app is in the background. didReceiveRemoteNotifification completionHandler doesn't get called! What should I look for and where can a problem be ? Can the square bracket be a problem for push notification ? To be even more precise, ios doesn't post any alerts/badges/banners from that incoming notification.

推荐答案

对于每一个想寻求 GCM 背景之谜答案的可怜灵魂.我解决了,问题出在格式上.我发布了正确的格式以及将 Http 请求发送到 GCM 和一些消息所需的 Java 代码.所以Http请求的头部应该有两个字段,即:

For every poor soul wondering in quest for an answer to GCM background mystery. I solved it and the problem was in the format. I'm posting the right format as well as Java code needed to send Http request to GCM with some message. So the Http request should have two field in the header, namely:

Authorization:key="here goes your GCM api key"
Content-Type:application/json for JSON data type

那么消息正文应该是一个带有to"和notification"键的json字典.例如:

then the message body should be a json dictionary with keys "to" and "notification". For example:

{
  "to": "gcm_token_of_the_device",
  "notification": {
    "sound": "default",
    "badge": "2",
    "title": "default",
    "body": "Test Push!"
  }
}

这是一个简单的 java 程序(仅使用 java 库),它使用 GCM 向指定设备发送推送:

Here is the simple java program (using only java libraries) that sends push to a specified device, using GCM:

public class SendMessage {

    //config
    static String apiKey = ""; // Put here your API key
    static String GCM_Token = ""; // put the GCM Token you want to send to here
    static String notification = "{\"sound\":\"default\",\"badge\":\"2\",\"title\":\"default\",\"body\":\"Test Push!\"}"; // put the message you want to send here
    static String messageToSend = "{\"to\":\"" + GCM_Token + "\",\"notification\":" + notification + "}"; // Construct the message.

    public static void main(String[] args) throws IOException {
        try {

            // URL
            URL url = new URL("https://android.googleapis.com/gcm/send");

            System.out.println(messageToSend);
            // Open connection
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // Specify POST method
            conn.setRequestMethod("POST");

            //Set the headers
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "key=" + apiKey);
            conn.setDoOutput(true);

            //Get connection output stream
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());

            byte[] data = messageToSend.getBytes("UTF-8");
            wr.write(data);

            //Send the request and close
            wr.flush();
            wr.close();

            //Get the response
            int responseCode = conn.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);
            System.out.println("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            //Print result
            System.out.println(response.toString()); //this is a good place to check for errors using the codes in http://androidcommunitydocs.com/reference/com/google/android/gcm/server/Constants.html

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这篇关于让 GCM 在后台为 iOS 设备工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆