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.