|
Antwort |
Registriert seit: 17. Mär 2010 46 Beiträge |
#1
Hallo Zusammen,
ich richte gerade Push Notifications an meine App ein. In FMX verwende ich dazu "Grijjy.RemotePush.Receiver". Ich teste das auf dem Mac mit (die Variablen sind gesetzt): curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: alert" --header "authorization: bearer $AUTHENTICATION_TOKEN" --data '{"aps":{"alert":"test"}}' --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN} Dieser Push klappt, ich bekomme Status 200 und die Notification kommt bei der App an. Jetzt versuche ich aber "stille" Notifications zu senden, um der App zu sagen, das neue Daten vorhanden sind. https://developer.apple.com/document...es_to_your_app Ich teste das auf dem Mac mit: curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: background" --header "authorization: bearer $AUTHENTICATION_TOKEN" --header "apns-priority: 5" --data '{"aps":{"content-available" : 1}}' --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN} Auch hier kommt Status 200 raus, aber diese Notification kommt nicht in der App an. Ich vermute mal es liegt daran, das diese Notifications laut Apple an application(_:didReceiveRemoteNotification:fetchCo mpletionHandler gesendet werden. Aber wie komme ich da dran / wie setze ich diesen Handler. Grüße Thomas Geändert von friedt99 (18. Sep 2022 um 12:39 Uhr) |
Zitat |
Registriert seit: 17. Mär 2010 46 Beiträge |
#2
So, habe es jetzt mit
TMessageManager.DefaultManager.SubscribeToMessage( TPushRemoteNotificationMessage,HandleRemoteNotific ationReceived); versucht. Da kommt aber immer noch keine Notification an. |
Zitat |
Registriert seit: 17. Mär 2010 46 Beiträge |
#3
Keine Ahnung warum, aber nun klappt es.
Habe es nochmal mit dem hier geposteten curl versucht, auch das klappt nun, auch ohne TMessageManager.DefaultManager.SubscribeToMessage, es genügt die Unit "Grijjy.RemotePush.Receiver". Grüße Thomas |
Zitat |
Registriert seit: 17. Mär 2010 46 Beiträge |
#4
Hier mal eine Anleitung wie man Push Notifications unter IOS mit APN zum Laufen bekommt da ich
ziemlich lange gebraucht habe. Basis ist Delphi 11.1 und XCode 13.4.1 und eine App (mit allen Einstellungen in Apple Developer) die man zumindest auf einem Entwicklungsgerät ausführen kann. Remote Push Notifications sind Notifications die von "außen" an ein Device gesendet werden. 1.) In Apple Developer ist folgendes unter "Certificates, Identifiers & Profiles zu tun: a.) unter Certificates ein Zertifkat für "Services" "Apple Push Notification service SSL (Sandbox & Production)" anlegen und auf den Mac herunterladen. Datei öffnen damit das Zertifikat im Schlüsselbund eingetragen wird. b.) Unter "Identifiers" den App Identifier bearbeiten (NICHT XC Wildcard) und dort den Haken bei "Push Notifications" setzen und mit "Edit" dann das Zertifikat für beide Optionen zuordnen. c.) Unter Profiles das Profile vom Typ "AppStore" bearbeiten, speichern, herunterladen und öffnen. Wenn das Profil vom Typ "Development" auf den Identifier "XC Wildcard" eingestellt ist (damit man Demo Projekte einfach auf das Entwicklungsgerät bekommt), dann am besten ein weiteres Profil z.B. "Development PUSH" anlegen. Push Notifications gehen nur bei einem Profil mit dem echten App Identifier (country.domain.appname). Im (neuen) Profil dann also den echten App Identifier auswählen, dann sollte unter "Enabled Capabilities" der Eintrag "Push Notifications" sichtbar sein. Das neue Profil herunterladen und öffnen damit es in XCode installiert wird. d.) Unter Keys einen neuen Schlüssel anlegen und dort "Apple Push Notification Service (APNs) aktivieren. Zum Abschluß den Schlüssel herunterladen (Dateiendung wird .p8) und gut aufbewahren, die Datei wird für das Senden der Push Notification z.B. via Curl oder PHP benötigt. e.) Die "Key ID" des soeben angelegten Keys notieren. f.) Unter "Membership" die Team ID heraussuchen und notieren (wird für das Senden benötigt) g.) Die App ID heraussuchen und notieren. 2.) In Delphi ist folgendes zu tun: a.) Im App Projekt unter "Versionsinformation" den Schlüssel "UIBackgroundModes" um "remote-notification" ergänzen. b.) Im App Projekt unter "Bereitstellung - Provisioning" das Development Profile auswählen, welches in Apple Developer unter Enabled Capabilities" den Eintrag "Push Notifications" hat, z.B. "Development PUSH". c.) Folgende Unit herunterladen und im Suchpfad ablegen: https://github.com/grijjy/GrijjyFoun...h.Receiver.pas 3.) Im Source folgendes einbauen:
Delphi-Quellcode:
Die App einmal starten / Debuggen und den Token auslesen und notieren.
uses ...Grijjy.RemotePush.Receiver;
TForm1 = Class(TForm) .. private FReceiver:TgoRemotePushReceiver; procedure HandlePushTokenChanged(const Sender: TObject; const M: TMessage); procedure HandlePushMessageReceived(const Sender: TObject; const M: TMessage); -- end; TForm1.FormCreate(Sender: TObject); begin ... FReceiver:=TgoRemotePushReceiver.Create(''); TMessageManager.DefaultManager.SubscribeToMessage(TgoDeviceTokenChangeMessage, HandlePushTokenChanged); TMessageManager.DefaultManager.SubscribeToMessage(TgoRemoteNotificationMessage, HandlePushMessageReceived); end; TForm1.FormDestroy(Sender: TObject); begin ... FReceiver.Free; end; procedure TForm1.HandlePushTokenChanged(const Sender: TObject; const M: TMessage); begin if (M is TgoDeviceTokenChangeMessage) then begin // Token an den Sender (z.B. PHP Webservice) übermitteln // Token steht in: TgoDeviceTokenChangeMessage(M).DeviceToken end; end; procedure TForm1.HandlePushMessageReceived(const Sender: TObject; const M: TMessage); begin if (M is TgoRemoteNotificationMessage) then begin // Die Nachricht verarbeiten. // TgoRemoteNotificationMessage(M).DataKey enthält den Provider (aps, fmc) // TgoRemoteNotificationMessage(M).Json enthält den JSON String der Notification end; end; 4.) Um das zu testen, auf dem Mac im Terminalfenster folgendes ausführen (eigene ID's / Pfade ergänzen) Siehe auch hier: https://developer.apple.com/document...and-line_tools unter dem Abschnitt "Send a Push Notification Using a Token" a.) diverse Variablen anlegen
Code:
b.) Verbindungstest
TEAM_ID=<hier Team ID eintragen>
AUTH_KEY_ID=<Key ID des oben angelegten Key eintragen> TOPIC=<App ID der App eintragen> APNS_HOST_NAME=api.sandbox.push.apple.com DEVICE_TOKEN=<den Device Token der bei HandlePushTokenChanged beim Programmstart erzeugt wird, hier eintragen> TOKEN_KEY_FILE_NAME=<Pfad auf die Schlüsseldatei (.p8) angeben, z.B. /Users/<username>/Downloads/<Name der Datei>.p8
Code:
c.) Authentication Token erzeugen (muß alle 20min erneuert werden)
openssl s_client -connect "${APNS_HOST_NAME}":443
Code:
d.) Test ausführenJWT_ISSUE_TIME=$(date +%s) JWT_HEADER=$(printf '{ "alg": "ES256", "kid": "%s" }' "${AUTH_KEY_ID}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =) JWT_CLAIMS=$(printf '{ "iss": "%s", "iat": %d }' "${TEAM_ID}" "${JWT_ISSUE_TIME}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =) JWT_HEADER_CLAIMS="${JWT_HEADER}.${JWT_CLAIMS}" JWT_SIGNED_HEADER_CLAIMS=$(printf "${JWT_HEADER_CLAIMS}" | openssl dgst -binary -sha256 -sign "${TOKEN_KEY_FILE_NAME}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =) AUTHENTICATION_TOKEN="${JWT_HEADER}.${JWT_CLAIMS}.${JWT_SIGNED_HEADER_CLAIMS}"
Code:
Es sollte dann ein http/2 Status von 200 angezeigt werden und die Notification in der App unter HandlePushMessageReceived aufschlagen.
curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: alert" --header "authorization: bearer $AUTHENTICATION_TOKEN" --data '{"aps":{"alert":"test"}}' --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN}
Ansonsten Fehlermeldungen lesen und ggf. Angaben (Pfade / ID's) kontrollieren. 5.) Um per PHP eine Notification an ein Device zu senden, kann dieser Code verwendet werden
PHP-Quellcode:
6.) Um "Stille" Notification zu senden, sind folgende Änderungen notwendig:
<?php
//Retrieved from [url]https://stackoverflow.com/questions/70105632/can-this-php-script-still-be-used-to-send-test-push-notifications-using-apns-c[/url] //Provide some variables $Cert = '<Pfad auf die Schlüsseldatei (.p8) angeben, /Pfad/<Name der Datei>.p8>'; $DeviceToken = '<den Device Token der bei HandlePushTokenChanged beim Programmstart erzeugt wird, hier eintragen>'; $PushType = 'alert'; $Url = 'https://api.sandbox.push.apple.com:443'; $Topic = '<App ID der App eintragen>'; $KeyID = '<Key ID des oben angelegten Key eintragen>'; $TeamID = '<hier Team ID eintragen>'; //generate token. Needs to be done at least every 20 minutes. Generated token could be kept in a file for 20 min to speed up. //https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns $assocToken = array(); $assocToken['alg'] = 'ES256'; //The encryption algorithm you used to encrypt the token. APNs supports only the ES256 algorithm, so set the value of this key to ES256. $assocToken['kid'] = $KeyID; //The 10-character Key ID you obtained from your developer account $assocToken['iss'] = $TeamID; //The issuer key, the value for which is the 10-character Team ID you use for developing your company’s apps. Obtain this value from your developer account. $assocToken['iat'] = time(); //The “issued at” time, whose value indicates the time at which this JSON token was generated. Specify the value as the number of seconds since Epoch, in UTC. The value must be no more than one hour from the current time. $header = '{' . ' "alg" : "'.$assocToken['alg'].'",' . ' "kid" : "'.$assocToken['kid'].'"' . '}'; $payload = '{' . ' "iss" : "'.$assocToken['iss'].'",' . ' "iat" : "'.$assocToken['iat'].'"' . '}'; $headerB64URL = base64url_encode($header); $payloadB64URL = base64url_encode($payload); $secret = file_get_contents($Cert); $signature = ''; openssl_sign($headerB64URL.'.'.$payloadB64URL, $signature, $secret, \OPENSSL_ALGO_SHA256); $ServerToken = $headerB64URL.'.'.$payloadB64URL.'.'.base64url_encode($signature); //token generated, send notification $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => $Url . '/3/device/'.$DeviceToken, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 1, CURLOPT_TIMEOUT => 10, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTPHEADER => array( "authorization: bearer " . $ServerToken, "apns-push-type: " . $PushType, "apns-topic: " . $Topic, ), CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_POST => '1', CURLOPT_POSTFIELDS => '{"aps":{"alert":"test"}}' )); $response = curl_exec($curl); if(curl_errno($curl) == 0){ return True; } else{ return False; }; ?> Stille Notifications sind Notifications die der Anwender niemals sieht. Diese sind nur gedacht, die Anwendung mit neuen / geänderten Daten zu versorgen bzw. diese zu Informieren, neue Daten abzurufen. Test ausführen
Code:
Notification per PHP senden
curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: background" --header "authorization: bearer $AUTHENTICATION_TOKEN" --data '{"aps":{"content-available":1}}' --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN}
PHP-Quellcode:
Hoffe das hilft mal jemand.
$PushType = 'background';
curl_setopt_array($curl, array( CURLOPT_URL => $Url . '/3/device/'.$DeviceToken, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 1, CURLOPT_TIMEOUT => 10, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTPHEADER => array( "authorization: bearer " . $ServerToken, "apns-push-type: " . $PushType, "apns-topic: " . $Topic, "apns-priority: 5" ), CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_POST => '1', CURLOPT_POSTFIELDS => '{"aps":{"content-available":1}}' )); Grüße Thomas Geändert von friedt99 (18. Sep 2022 um 20:59 Uhr) |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |