webentwicklung-frage-antwort-db.com.de

Damit GCM für iOS-Geräte im Hintergrund funktioniert

Ich versuche, GCM für IOS - und Android-Clients zu verwenden. Es scheint gut mit IOS zu funktionieren, wenn sich die App im Vordergrund befindet. Wenn sich die App im Hintergrund befindet, erhält das Benachrichtigungscenter jedoch keine Nachricht und didReceiveRemoteNotification with completionHandler wird nicht aufgerufen.

Ich habe ein Problem als falsch formatierte Nachricht von GCM an APNS erkannt. So sieht es aus: 

 [Nachricht: Neue Nachricht, collapse_key: do_not_collapse, von: **************]
Während die Push-Benachrichtigungen für IOS aps in der Benachrichtigung enthalten sollten, habe ich Recht? Wie auch der verfügbare Inhalt ist auf 1 gesetzt. Zum Beispiel:

{ "aps": { "content-available": 1 }, "Daten-ID": 345 }

Übrigens, im Vordergrund empfängt die App die Nachricht trotzdem, das Problem liegt nur im Hintergrund. Irgendwelche Ratschläge, wie ich ein Problem angehen sollte, damit GCM sowohl für ios als auch für Android funktioniert?

UPDATE: Das habe ich im Netz gefunden:

In Bezug auf die tatsächliche Kommunikation verwendet GCM, solange sich die Anwendung auf einem iOS-Gerät im Hintergrund befindet, APNS zum Senden von Nachrichten. Die Anwendung verhält sich ähnlich wie das Benachrichtigungssystem von Apple. Wenn die App jedoch aktiv ist, kommuniziert GCM direkt mit der App

Also die Nachricht, die ich im Vordergrundmodus erhalten habe:

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

War die direkte Nachricht von GCM (APNS hat an dieser Angelegenheit überhaupt nicht teilgenommen). Die Frage ist also: formatiert APNS das, was GCM an das ios-Benachrichtigungsformat sendet, neu? 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 eingehender Daten von APNS anzuzeigen?

UPDATE: Okay, ich habe die Struktur der Nachricht geändert und jetzt im Vordergrundmodus erhalte ich die folgende Nachricht:

Benachrichtigung erhalten: ["aps": {"alert": "Einfache Nachricht", "Inhalt verfügbar": 1}, collapse_key: do_not_collapse, von: **************]

Jetzt scheint es gut formatiert zu sein, aber es gibt immer noch keine Reaktion, wenn sich die App im Hintergrund befindet. didReceiveRemoteNotifification completionHandler wird nicht gerufen! Worauf muss ich achten und wo kann ein Problem sein? Kann die eckige Klammer ein Problem für die Push-Benachrichtigung sein? Um genauer zu sein, stellt ios keine Warnungen/Badges/Banner aus dieser eingehenden Benachrichtigung bereit.

25
Olexiy Burov

Für jede arme Seele, die sich auf der Suche nach einer Antwort auf das GCM-Hintergrundgeheimnis wundert. Ich habe es gelöst und das Problem lag im Format. Ich poste das richtige Format sowie den Java-Code, der zum Senden einer HTTP-Anforderung an GCM erforderlich ist, mit einer Nachricht .. Die HTTP-Anforderung sollte also zwei Felder im Header enthalten, und zwar:

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

dann sollte der Nachrichtentext ein Json-Wörterbuch mit den Schlüsseln "bis" und "Benachrichtigung" sein. Zum Beispiel:

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

Hier ist das einfache Java-Programm (das nur Java-Bibliotheken verwendet), das Push mit GCM an ein bestimmtes Gerät sendet:

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

Beachten Sie, dass auf iOS-Geräten, wenn Ihre App, die GCM verwendet, beendet wurde (im App-Switcher geklaut wurde), Ihr Gerät nur bei Erhalt einer Nachricht aktiviert wird, wenn Sie eine Benachrichtigung mit "Benachrichtigung", "content_available" und senden "Priorität" (auf "Hoch" gesetzt). Wenn Sie das eine oder das andere haben, kann es funktionieren, wenn die App beendet wurde. Sobald die App jedoch beendet wurde, MÜSSEN Sie alle 3 dieser Schlüssel in Ihrer Benachrichtigungsnutzlast haben.

Etwas wie das:

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

Versuchen Sie, den Prioritätsschlüssel in Ihrer Nutzlast entsprechend den folgenden Dokumenten festzulegen: https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message

  • die normale Priorität ist in der APN-Terminologie gleich 5
  • die hohe Priorität ist in der APN-Terminologie gleich 10

Hier finden Sie weitere Informationen zu den Prioritäten von Apple APNs und dessen Verhalten: https://developer.Apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html

Beispielnutzlast:

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

Mit nodeJS und der Bibliothek " node-gcm npm" habe ich festgestellt, dass die folgende Nutzlast für iOS funktioniert. Für Android sende ich eine etwas andere Nutzlast, da ich alle Push-Benachrichtigungen abfangen möchte, bevor sie im angezeigt werden System Tray:

{ 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 müssen Sie sicherstellen, dass Ihre iOS-App die eingehende Benachrichtigung verarbeiten kann. Dies sollte jedoch geschehen, wenn sich Ihre App im Hintergrund befindet.

0
GreensterRox
  1. Hatte dies für C #, ich denke, das könnte helfen. Ich hatte auch dieses Problem Laut der Dokumentation von __.Apple erkennt das Betriebssystem, dass es eine __.-Benachrichtigung gibt, wenn sich die App im Hintergrund befindet.

        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