web-dev-qa-db-fra.com

Faire en sorte que GCM fonctionne pour un périphérique iOS en arrière-plan

J'essaie d'utiliser GCM pour les clients IOS et Android. Cela semble fonctionner correctement avec IOS lorsque l'application est au premier plan. Toutefois, lorsque l'application est en arrière-plan, le centre de notification ne reçoit pas le message et didReceiveRemoteNotification with completionHandler n'est pas appelé.

J'ai identifié un problème comme un message mal formaté de GCM à APNS. À savoir, c'est à ça que ça ressemble: 

 [message: Nouveau message, collapse_key: do_not_collapse, from: **************]
Alors que les notifications push IOS devraient avoir la clé aps dans la notification, ai-je raison? Ainsi que content-available mis à 1. Par exemple:

{ "aps": { "contenu disponible": 1 }, "data-id": 345 }

En passant, dans l'application de premier plan qui reçoit le message de toute façon, le problème ne concerne que l'arrière-plan. Avez-vous des conseils sur la façon dont je devrais aborder un problème pour que GCM fonctionne à la fois pour iOS et Android?

UPDATE: C'est ce que j'ai trouvé sur le net:

En ce qui concerne la communication réelle, tant que l’application est en arrière-plan sur un périphérique iOS, GCM utilise APNS pour envoyer des messages, l’application se comportant de la même manière que le système de notification d’Apple. Mais lorsque l'application est active, GCM communique directement avec l'application.

Donc, le message que j'ai reçu en mode avant-plan:

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

C’était le message direct de GCM (APNS n’a pas du tout participé à cette affaire). La question est donc la suivante: APNS reformate-t-il ce que GCM lui envoie pour qu’il adhère au format de notification iOS? Si tel est le cas, comment savoir si APNS fait quelque chose et si elle m'envoie une notification sous un format différent? Existe-t-il un moyen d’afficher les journaux des données entrantes d’APNS?

UPDATE: .__ D'accord, j'ai réussi à modifier la structure du message et maintenant, en mode avant-plan, je reçois le message suivant:

Notification reçue: ["aps": {"alert": "Message simple", "content-available": 1}, clé_collapse: do_not_collapse, from: **************]

Maintenant, il semble être bien formaté, mais il n'y a toujours pas de réaction lorsque l'application est en arrière-plan. didReceiveRemoteNotifification completionHandler n'est pas appelé! Que devrais-je rechercher et où peut se poser un problème? Le crochet peut-il poser problème pour la notification Push? Pour être encore plus précis, ios n'envoie pas d'alertes/badges/bannières à partir de cette notification entrante.

25
Olexiy Burov

Pour chaque pauvre âme en quête d'une réponse au mystère de GCM. Je l'ai résolu et le problème était dans le format. Je poste le bon format ainsi que le code Java nécessaire pour envoyer une requête HTTP à GCM avec un message . La requête HTTP doit donc comporter deux champs dans l'en-tête, à savoir:

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

alors le corps du message devrait être un dictionnaire json avec les clés "to" et "notification". Par exemple:

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

Voici le programme Java simple (utilisant uniquement les bibliothèques Java) qui envoie Push à un périphérique spécifié, à l'aide de 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();
        }
    }
}
26
Olexiy Burov

Il est important de noter que sur les appareils iOS, si votre application utilisant GCM a été supprimée (balayée dans le commutateur d'applications), votre appareil ne s'activera à la réception d'un message que si vous envoyez une notification avec la "notification", "content_available" "priorité" (réglé sur "élevé"). Si vous avez l'un ou l'autre, cela peut fonctionner lorsque l'application a été supprimée. Mais une fois l'application supprimée, vous DEVEZ disposer de ces 3 clés dans la charge de notification.

Quelque chose comme ça:

{
    "to": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification": {
        "title": "test",
        "body": "my message"
    },
    "priority": "high",
    "content_available": true
}
23
jwenz723

Essayez de définir la clé de priorité dans Votre charge utile en fonction de la documentation, ici: https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message

  • la priorité normale est égale à 5 dans la terminologie des APN
  • haute priorité égale à 10 dans la terminologie des APN

Vous trouverez ici plus d’informations sur les priorités et les comportements des APN d’Apple ici: https://developer.Apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html

Exemple de charge utile:

{
  "to": "gcm_device_token",
  "priority": "high",
  "content_available": false,
  "notification": {
    "sound": "default",
    "badge": "1",
    "title": "Push Title",
    "body": "Push Body"
  }
}
7
Marcin Kapusta

À l’aide de nodeJS et de la bibliothèque node-gcm npm, j’ai constaté que la charge suivante fonctionnait pour moi pour iOS, pour Android, j’envoyais une charge légèrement différente, car je voulais intercepter toutes les notifications Push avant de les afficher dans le dossier. plateau de système:

{ dryRun: false,
  data: 
   { customKey1: 'CustomValue1',
     customKey2: 'CustomValue2',
     content_available: '1',
     priority: 'high' },
  notification: 
   { title: 'My Title',
     icon: 'ic_launcher',
     body: 'My Body',
     sound: 'default',
     badge: '2' } }

Bien sûr, vous devez vous assurer que votre application iOS peut gérer la notification entrante, mais cela doit se faire lorsque votre application est en arrière-plan.

0
GreensterRox
  1. Je l'ai fait pour C #, je pense que cela pourrait être une aide.J'ai également eu ce problème Selon la documentation de Apple, le système d'exploitation comprend ainsi qu'il existe une notification Lorsque l'application est en arrière-plan.

        JObject notification =new Object(
        new JProperty("to","put token which you get from running client application "),   
        new JProperty("content_available",true),
        new JProperty("priority","high"),
        new JProperty("notification",new JObject(
        new JProperty("title","message"),
        new JProperty("body","test message")
         ))
        );
    
0
ireshika piyumalie