How-To: Apple Push Notification Tutorial (inkl. PHP Skript)

Ich hatte heute etwas Zeit mich mit den Apple Push Notifications (APN) zu beschäftigen und eine meiner Apps damit „aufzurüsten“. Ich muss sagen diese steigern deutlich den Wert einer App, vor allem wenn der Benutzer sofort benachrichtigt werden kann wenn er z.B. eine neue Nachricht im System bekommen hat.

Falls ihr noch nicht viel damit gemacht habt möchte ich Euch ein wenig die „Angst“ nehmen und hier Schritt für Schritt zeigen wie dieses Feature eingerichtet wird. Abschließend habe ich auch ein kleines PHP-Skript abgedruckt welches dann eine Test-Notification an das iOS-Gerät sendet.

Zuerst geht Ihr natürlich im Developer Center in Euer iOS Provisioning Portal. Hier dann auf „App IDs“ klicken und bei der entsprechenden App dann „Configure“ aufrufen. Die folgende Maske sieht so aus:

Hier muss man bei „Development Push SSL Certificate“ ebenfalls auf „Configure“ klicken, wir wollen erstmal ein Entwickler-Zertifikat erstellen mit dem man etwas rumspielen kann. Danach erscheint folgender hinweis / Anleitung:

Halten wir uns mal an diese Anleitung. Also noch nicht auf „Continue“ klicken sondern erst ein Zertifikats-Request erstellen (Dies ist das gleiche wie im letzten Artikel beschrieben wurde).
Öffnet das Programm „Schlüsselbundverwaltung“ und klickt dort im Menü „Schlüsselbundverwaltung“ auf „Zertifikatsassistent“ und dann auf „Zertifikat einer Zertifizierungsstelle anfordern…“:

Im folgenden Fenster Eure E-Mail-Adresse angeben und den Namen (am besten noch vermerken dass es ein APN Key ist, bei sehr vielen privaten Schlüsseln im Schlüsselbund kann man diese einfach auseinanderhalten). Wichtig ist noch die Option „Auf Festplatte speichern“ zu aktivieren:

Die Zertifikatsanforderung dann einfach irgendwo speichern. Nachdem diese gespeichert wurde kann man im „Provisioning Portal“ dann weitermachen. In der Maske auf „Continue“ klicken und in der nächsten Maske dann die Zertifikatsanforderung hochladen:

Danach erscheint dann zuerst die Meldung dass das Zertifikat erstellt wird:

Kurze Zeit später ist das Zertifikat generiert und man kann es sich irgendwo auf der Festplatte abspeichern:

Wen Ihr Euch das Zertifikat heruntergeladen habt einfach einen Doppelklick darauf ausführen, es wird dann ebenfalls in Euren Schlüsselbund kopiert. Man sieht dies dann unter dem entsprechenden privaten Schlüssel:

Dies war der erste Teil der Prozedur. Kurze Zusammenfassung bisher: wir haben für unsere App im Provisioning Portal ein Zertifikat für die Push Notification Dienste erzeugt und dies in unseren Schlüsselbund aufgenommen.

Im folgenden Teil erzeugen wir ein kleines Bundle bestehend aus dem Zertifikat plus privaten Schlüssel. Dies wird nämlich für den Webserver benötigt der die Benachrichtigungen an das iOS-Gerät senden soll.

Also.. weiter geht’s. Öffnet Eure Schlüsselbundverwaltung, klickt dann links auf „Schlüssel“ und sucht den privaten Schlüssel für die APN Dienste (den wir im ersten Schritt erstellt haben). Ihr könnt dies auch gut sehen: Wenn Ihr diesen aufklappt sollte ein Eintrag mit dem Zertifikat „Apple Development Push Service …“ enthalten sein.

Dieser Schlüssel muss als erstes exportiert werden. Einfach ein Rechtsklick auf den Schlüssel ausführen und auf „… Key exportieren“ klicken:

Gebt als Namen einfach „apsKey“ ein:

Das „Kennwort“ für den Export kann leergelassen werden:

Nun müsst Ihr Euer MAC OS Kennwort eingeben um zu erlauben dass der Key exportiert wird:

Nun wurde der private Schlüssel als apsKey.p12 exportiert. Das gleiche muss noch für das Zertifikat erledigt werden. Wiederholt diese Schritte noch für das Zertifikat, also zuerst ein Rechtsklick auf das Zertifikat ausführen und dann auf „… exportieren“ aufrufen:

Als Name hier „apsCert“ eingeben:

Die letzten beiden Schritte sind identisch wie beim Export des Schlüssels. nun haben wir also irgendwo (z.B. auf dem Desktop) einen exportierten Schlüssel (apsKey.p12) und ein exportiertes Zertifikat (apsCert.p12) liegen.

Das nächste Ziel ist es beide als .pem-Datei „zusammenzuschnüren“. Dies kann man mit Hilfe des Programms „terminal“ durchführen. Startet also das Terminal, wechselt dann in das Verzeichnis in dem die .p12-Dateien liegen und ruft folgende Befehle auf:

openssl pkcs12 -clcerts -nokeys -out apsCert.pem -in apsCert.p12
openssl pkcs12 -nocerts -out apsKey.pem -in apsKey.p12

Dies wandelt die .p12 in .pem-Dateien um. Danach entfernen wir das Passwort von der apsKey.pem-Datei (nur wenn noch ein Passwort vorhanden ist!):

openssl rsa -in apsKey.pem -out apsKeyOhnePW.pem

Nun führen wir beide Dateien zusammen:

cat apsCert.pem apsKeyOhnePW.pem > apsDevBundle.pem

Dies Datei „apsDevBundle.pem“ ist für unseren Webserver wichtig. In ihr sind alle nötigen Zertifikate und Schlüssel enthalten um mit unserem PHP-Skript eine Nachricht an ein iOS-Gerät zu senden.

Ok, hier nochmal eine kurze Pause. Im zweiten Teil haben wir die generierten Zertifikate und Schlüssel exportiert und in ein für den Webserver verwertbares Format umgewandelt. Bevor der Webserver aber an unser iOS-Gerät etwas senden kann muss das Gerät die App ausführen welche etwas Code enthält und sich erstmal bei Apple „anmeldet“ dass Push-Benachrichtigungen empfangen werden können.

In der App einfach folgenden Eintrag in die applicationDidFinishLaunching: Methode einfügen:

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound)];

Und ins AppDelegate außerdem noch folgende Methoden einfügen:

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
	NSLog(@"devToken=%@",deviceToken);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
	NSLog(@"Error in registration. Error: %@", err);
}

In diesem Fall wird kein spezielle Code ausgeführt nachdem sich die App registriert hat. Apple gibt bei erfolgreicher Registrierung ein „Device Token“ zurück welches in diesem Beispiel in der Konsole angezeigt wird. Dieses Token merken wir uns – es wird im PHP-Skript benötigt um die Notification an ein bestimmtes Gerät zu senden! (Das Token besteht aus 64 Zeichen und ein paar Leerzeichen – die aber weggelassen werden können).

Kommen wir nun zu dem PHP-Skript welches ausgeführt werden kann um die Notification an das Gerät zu senden. Erstellt auf Eurem Webserver einfach eine Datei und kopiert die Datei apsDevBundle.pem in diesen Ordner hinein.

<?php
// APNs Push testen auf Token
$deviceToken = "XXXXXXXXX"; // Hier das Device-Token angeben, ist 64-stellig

// Payload erstellen und JSON codieren
$payload['aps'] = array('alert' => 'Hallo Sven!', 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);

$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apsDevBundle.pem';

// Stream erstellen
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);

$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if ($apns)
{
  // Nachricht erstellen und senden
  $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
  fwrite($apns, $apnsMessage);

  // Verbindung schliessen
  fclose($apns);
}
else
{
  echo "Fehler!";
  var_dump($error);
  var_dump($errorString);
}
?>

Geschafft! Denkt aber dran wenn Ihr dies in produktiven System einsetzt des .pen-Bundle an einen sicheren Ort zu kopieren von dem es nicht „heruntergeladen“ werden kann, also am besten in einen .htaccess-geschützten Ordner.

Über Fasty

iOS- und PHP-Entwickler My Google Profile+
Dieser Beitrag wurde unter iOS abgelegt und mit verschlagwortet. Setze ein Lesezeichen auf den Permalink.

16 Antworten auf How-To: Apple Push Notification Tutorial (inkl. PHP Skript)

  1. ben jamin sagt:

    Nice, werd ich heut ausprobieren,
    finde es immer noch schade, das apple es nicht zulässt bzw. möglich macht dass man ein Endgerät braucht um diese PushNotif. zu testen :S
    aber wird wohl in der Natur der Notification liegen XD

  2. Martin sagt:

    Hallo! Danke, Super erklärt! Vielleicht kanst du mir folgende Frage beantworten:
    – Wie kann man dann nicht nur an das mir bekannte Device mit dem mir bekannten Token Pushnachrichten schicken, sondern an alle, die die App installiert haben (also vielleicht 1000 Leute)?
    Grüsse
    Martin

    • Fasty sagt:

      Hallo Martin,
      das kann ich Dir leider nicht sagen, habe bisher für meine Projekte nur das Benachrichtigen einzelner Geräte benötigt. Ich weiß nicht ob dies möglich ist.

    • Maurice sagt:

      Hallo, das ist wirklich ein super Tutorial!

      Ich habe es so gelöst, dass ich eine mysql Datenbank habe, in welcher alle Tokens gespeichert sind. In der appdidRegister… Methode wird jetzt ein Eintrag in die mysql Datenbank auf dem Webserver erzeugt und das Token hinzugefügt. Beim pushen läuft das php Skript über die DB und pusht jedem Device die Notifikation einzeln zu. Ich weiß nicht ob das der ideale Weg ist aber bei mir läuft es.

      Ich habe mir jetzt im Nachhinein eine Production.pem Datei gebaut genauso wie auch die Dev.pem mit der dev.pem läuft alles, wenn ich die Production.pem zum pushen versende kommt nix an. Irgendjemand eine Idee, woran das liegt?

      Vielen Dank für das wunderbare Tutorial und Liebe Grüße…

      Maurice

  3. Yasin sagt:

    Hallo,

    vielen Dank erstmal für diese Anleitung. Finde es sehr gut, dass sich auch jemand Gedanken um deutsche Programmierer macht 🙂

    Habe leider ein Problem. Habe genau das gemacht wie in der Anleitung auch aber bekam dann folgenden Fehler:

    pushdeneme[929:707] Error in registration. Error: Error Domain=NSCocoaErrorDomain Code=3000 „Keine gültige aps-environment-Entitlement-Zeichenkette für Apps gefunden“ UserInfo=0x186570 {NSLocalizedDescription=Keine gültige aps-environment-Entitlement-Zeichenkette für Apps gefunden}

    • Fasty sagt:

      Hallo Yasin,

      weiß leider auch nicht genau an was das liegt. Es könnte aber daran liegen dass Du die Push-Zertifikate nachträglich erstellt hast.
      Im Developer Provisioning Portal musst Du quasi – nachdem Du die Zertifikate erstellt hast – das Zertifikat für die App (Developer oder Distribution) noch einmal neu erstellen (am besten auf „Modify klicken und irgendwas ändern“) und nochmal herunterladen und in die App einbauen. Denn erst dann sind in dem Provisioning Zertifikat die Infos zu den Push Diensten enthalten.

      Ich hiffe das hilft 😉

  4. Jan sagt:

    Hi, ich hab mal einen Vergleich der unterschiedlichen Push Verfahren gemacht:
    Push Notification

    Viele Grüße,

    Jan

  5. Hallo Sven,

    ein hervorragendes Tutorial. Hat mich nur ca. eine halbe Stunde gekostet, das testweise in mein App aufzunehmen. Jetzt muss ich das ganze nur noch mit Leben füllen 😉

    Gruß

    Marcel

  6. Roger sagt:

    Hi, was muss ich für eine PEM pass Phrase eingeben?
    Ich bekommen im Terminal folgende Meldung:

    localhost:Desktop roger$ openssl pkcs12 -nocerts -out apsKey.pem -in apsKey.p12
    Enter Import Password:
    MAC verified OK
    Enter PEM pass phrase:
    Verifying – Enter PEM pass phrase:
    phrase is too short, needs to be at least 4 chars
    Enter PEM pass phrase:

    Wenn ich nur auf Enter drücke klappt es nicht.

  7. Schöner Post. Sehr gut strukturiert und funktional. Danke.

  8. Jan sagt:

    Hallo zusammen!

    Ich habe euer PHP-Script getestet und bekam die unten stehenden Fehler angezeigt. Hat von euch einer eine Idee, woher diese Fehler kommen? Es hat wohl irgendetwas mit den Zertifikaten zu tun. Kennt ihr euch besser aus?

    Gruß
    Jan

    Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure in fktn.push.php on line 15

    Warning: stream_socket_client(): Failed to enable crypto in fktn.push.php on line 15

    Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in fktn.push.php on line 15

    • Udo sagt:

      Hallo, Jan, ging mir auch so, schau mal unten, hat mir geholfen

      Click the disclosure arrow next to your certificate in Keychain Access and select the certificate and the key.
      Right click and choose Export 2 items….
      Choose the p12 format from the drop down and name it cert.p12.
      Now covert the p12 file to a pem file:

      $ openssl pkcs12 -in cert.p12 -out apple_push_notification_production.pem -nodes -clcerts

      • Sebastian Scharf sagt:

        Danke!!!!!! Ich habe 5 Stunden damit verbracht den Fehler zu suchen und mindestens 20 lange Artikel gelesen ohne Lösung. Diese zwei Zeilen haben alles gelöst und es funktioniert!!! Danke vielmals!!

  9. Nico sagt:

    Hey,

    bin gerade dabei Push-Notifications in 4stats zu implementieren und bin dabei auf Deinen Blog gestossen. 1. Platz in Google – Klasse 😉 Danke Dir für das ausführliche Tutorial! Hat wunderbar geklappt.

    Viele Grüsse nach Roßdorf und/oder Halver
    Nico

  10. Neo sagt:

    Vielen Dank für die Anleitung.
    Die hilft mir jedes mal weiter – gerade den Teil mit den ganzen Zertifikaten und Keys 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.