25

Ich versuche, GCM für IOS- und Android-Clients zu verwenden. Es scheint mit IOS gut zu funktionieren, wenn die Anwendung im Vordergrund ist. Wenn die Anwendung jedoch im Hintergrund ausgeführt wird, empfängt das Benachrichtigungscenter die Nachricht nicht und didReceiveRemoteNotification with completionHandler wird nicht aufgerufen.GCM für iOS-Gerät im Hintergrund arbeiten

Ich identifizierte ein Problem als eine falsch formatierte Nachricht von GCM zu APNS. Nämlich, so sieht es aus:

 
[message: New message, collapse_key: do_not_collapse, from: **************]
Während die IOS-Push-Benachrichtigungen aps Schlüssel in der Benachrichtigung haben sollen, habe ich recht? Sowie inhalts verfügbaren Satz auf 1. Beispiel:

{ "aps": { "Content-verfügbar": 1 }, "Daten-ID" 345 }

Durch Der Weg, in der App im Vordergrund die Nachricht trotzdem erhält, ist das Problem nur mit dem Hintergrund. Irgendwelche Ratschläge, wie soll ich ein Problem angehen, damit GCM sowohl für iOS als auch für Android funktioniert?

UPDATE: Das ist, was ich im Netz gefunden: im Hintergrund auf einem iOS-Gerät

In Bezug auf die eigentliche Kommunikation, solange die Anwendung ist, verwendet GCM APNS Nachrichten zu senden, die Die Anwendung verhält sich ähnlich wie das Benachrichtigungssystem von Apple. Aber wenn die App aktiv ist, GCM kommuniziert direkt mit der App

So ist die Botschaft, die ich im Vordergrund Modus erhalten:

[Nachricht: Neue Nachricht, collapse_key: do_not_collapse, ab: *** ***********]

War die direkte Nachricht von GCM (APNS war überhaupt nicht an dieser Affäre beteiligt). Die Frage ist also: Formatiert APNS das, was GCM an das ios-Benachrichtigungsformat sendet? Wenn ja, woher weiß ich, dass APNS tatsächlich etwas tut und ob es mir eine Benachrichtigung in einem anderen Format sendet? Gibt es eine Möglichkeit, Protokolle von eingehenden Daten von APNS anzuzeigen?

UPDATE: Okay, habe ich es geschafft, die die Struktur der Nachricht zu ändern und jetzt im Vordergrund Modus ich die folgende Meldung angezeigt:

Mitteilung erhalten: [ "aps": { "alert" : "Simple Nachricht", "Content-verfügbar": 1}, collapse_key: do_not_collapse, ab: **************]

Nun scheint es gut formatiert zu werden, Aber es gibt immer noch keine Reaktion, wenn die App im Hintergrund ist. didReceiveRemoteNotification completionHandler wird nicht aufgerufen! Nach was soll ich suchen und wo kann ein Problem sein? Kann die eckige Klammer ein Problem für Push-Benachrichtigungen sein? Um noch genauer zu sein, sendet ios keine Benachrichtigungen/Abzeichen/Banner aus dieser eingehenden Benachrichtigung.

+0

Bitte überprüfen http://stackoverflow.com/a/34075999/471499 –

Antwort

26

Für jede arme Seele, die sich auf der Suche nach einer Antwort auf das GCM-Hintergrundmysterium wundert. Ich habe es gelöst und das Problem war im Format. Ich posten das richtige Format sowie Java-Code benötigt, um HTTP-Anfrage an GCM mit einer Nachricht zu senden. So sollte die HTTP-Anforderung zwei Feld im Kopf hat, nämlich:

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

dann der Nachrichtentext ein json Wörterbuch mit Schlüssel sein sollte „auf“ und „Benachrichtigung“. Zum Beispiel:

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

Hier ist das einfache Java-Programm (mit nur Java-Bibliotheken), die Push auf einen bestimmten Gerät sendet, GCM mit:

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(); 
     } 
    } 
} 
+0

Ja, * der Java-Code für die Arbeiten, und ich bin in der Lage zu sehen, meine Push in der Notification-Schublade, aber keiner meiner 'didReceiveRemoteNotification Entsendung' Methoden werden angerufen. Das bedeutet, dass ich den Schub bekomme, aber ich kann ihn nicht abfangen ?! Wie hast du das gelöst? –

+0

Mit anderen Worten, ich denke, dass meine App nicht geweckt wird, weil ich nicht "content-available": "1" über meinen Server setze. Wie und wo hast du das gemacht?Ich habe versucht, diesen Schlüssel in den Benachrichtigungsschlüssel hinzufügen, aber es funktioniert nicht –

+3

Sie sollten es in den HTTP-Anfrage-Körper setzen. In diesem speziellen Beispiel fügen Sie einfach "content_available": "1" als Schlüssel für messageToSend-Zeichenfolge hinzu. –

7

Try Einstellung Priorität Schlüssel in Ihrer Nutzlast nach dem hier docs: https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message

  • normale Priorität ist bis 5 in APNs Terminologie
  • gleich
  • hohe Priorität 10 gleich in APNs Terminologie

Hier haben Sie weitere Informationen über Apple-APNs Prioritäten und sein Verhalten hier: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html

Beispiel Nutzlast:

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

Die Datennutzlast und Benachrichtigungsnutzlast sind beide für iOS und Android verfügbar. Bei iOS besteht der Unterschied darin, dass Benachrichtigungs-Payload über APNS gesendet wird, während Daten-Payload über die eigene Verbindung von GCM gesendet wird, die nur dort vorhanden ist, wenn sich die App im Vordergrund befindet. SO, Wenn ich GCM sowohl in Android als auch in iOS verwenden möchte, sollte die Payload nur Benachrichtigungen enthalten oder sind sowohl Daten als auch Benachrichtigungen in Ordnung? – abhi1992

+0

Was bedeuten die Daten im letzten Satz? –

+0

Die Payload kann entweder "Daten" oder "Benachrichtigung" richtig sein? Https: //developers.google.com/cloud-messaging/concept-options – abhi1992

23

Es ist wichtig, dass auf iOS-Geräten zu beachten, wenn Ihre App, die GCM verwendet, wurde getötet (im App-Switcher geklaut). Ihr Gerät wird erst nach dem Empfang einer Nachricht aktiviert, wenn Sie eine Benachrichtigung mit "Benachrichtigung", "content_available" und "priority" (auf "high") senden. Wenn Sie das eine oder das andere haben, kann es funktionieren, wenn die App getötet wurde. Aber sobald die App getötet wurde, MÜSSEN Sie alle drei dieser Schlüssel in Ihrer Benachrichtigungsnutzlast haben.

Etwas wie folgt aus:

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

Danke! sparen von stunden in meinem problem mit ios im hintergrund .... –

+0

Im Ernst, diese Antwort war ein großer Helfer. – abhi1992

0
  1. tat dies für C#, denken, dies könnte help.I hatte auch dieses Problem nach der Zugabe von content_available auf true, es funktionierte. Laut Apple-Dokumentation, das ist die Art und Weise OS verstehen, dass es eine Benachrichtigung gibt, wenn App im Hintergrund ist.

    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

Mit NodeJS und der node-gcm npm Bibliothek, die ich gefunden habe, dass die folgende Nutzlast für mich arbeitet für iOS, Android für mir eine etwas andere Nutzlast bin das Senden, weil ich vor allem Push-Benachrichtigungen abfangen will,

{ 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' } } 

natürlich Sie brauchen, um sicherzustellen, dass Ihr iOS-App die eingehende Meldung verarbeiten kann, aber dies sollte kommen durch, wenn die App im Hintergrund ist: sie in der Taskleiste zeigt.