Lors de l'envoi de notifications aux utilisateurs iOS, je reçois pour certains d'entre eux le code de statut de réponse 400 (BadDeviceToken) ou le code 410 (non enregistré).
De la documentation Apple sur "BadDeviceToken":
Le jeton de périphérique spécifié était mauvais. Vérifiez que la demande contient un jeton valide et que le jeton correspond à l'environnement.
Quelle est la signification de "mauvais"? Je sais pertinemment que le jeton de périphérique était valide à une époque antérieure. Que fait un utilisateur pour rendre son jeton de périphérique incorrect?
De la documentation sur "Non enregistré":
Le jeton de périphérique est inactif pour le sujet spécifié.
Cela signifie-t-il nécéssairement que l'application a été supprimée? Ou il peut y avoir d'autres raisons pour cette réponse.
Comme vous l'avez cité dans Tableau 8-6 dans la documentation d'APNS, il existe deux causes possibles de l'erreur:
S'il s'agit du premier cas, assurez-vous que l'application iOS enregistre le périphérique pour les notifications à distance à chaque lancement de l'application, car le jeton de périphérique a de nombreuses raisons de changer au cours des lancements, comme indiqué dans Configuration du support de notification à distance .
Si c'est le deuxième cas, vous devez vous assurer que:
Heureusement, en tant que développeur iOS, vous n'avez pas besoin de modifier directement les droits APNS vous-même. Il est toujours en développement et n'est automatiquement modifié par Xcode en production que lorsque vous générez la construction et l'exportation pour App Store ou la distribution d'entreprise. En ce qui concerne le backend, votre développeur backend doit savoir comment le configurer pour les environnements de développement et de production. Pour certains frameworks, il suffit de basculer un booléen nommé isProduction
. En fin de compte, conformément à Communication avec les APN dans la section APNs Connections
, les notifications push sont envoyées à différents noeuds finaux APNS selon que l’environnement est en production ou en développement.
Supposons que l'erreur BadDeviceToken
soit due au second cas, à savoir que le jeton de périphérique enregistré par l'application ne correspond pas à l'environnement de développement correctement configuré du backend. Tout d'abord, dans votre projet Xcode, vérifiez votre fichier .entitlements
et vérifiez que la valeur de la clé APS Environment
est development
. Ça devrait ressembler à ça:
Après avoir créé une archive, ouvrez l’Organiseur (via le menu Window
> Organizer
), sélectionnez l’archive, puis cliquez sur Export...
à droite. Vous devriez voir quatre méthodes de distribution:
Si vous sélectionnez App Store ou Entreprise, vous verrez dans les boîtes de dialogue suivantes que Xcode modifie les droits d'accès APNS à la production (voir le bout de la flèche rouge):
Si vous sélectionnez Ad Hoc ou Development, le texte sous aps-environment sera development
, ce qui devrait alors correspondre aux configurations du backend.
Code d'état "400": vous obtenez cette erreur lorsque vous essayez d'envoyer la notification avec un certificat incorrect. Assurez-vous que vous utilisez un certificat de production pour un environnement de production. C'est mauvais parce que vous utilisez de mauvaises configurations.
Code d'état '410': Oui, avec ce code, nous pouvons comprendre que l'application a été supprimée. Dans notre application, lorsque nous obtenons ce code d'état, nous supprimons ce jeton de la base de données. L'autre scénario pourrait être que l'utilisateur a réinstallé l'application, ce qui pourrait changer son jeton. Il est donc préférable de supprimer ce jeton.
Code d'erreur 404: jeton BadDevice
Raisons possibles:
Remarque: Ajoutez .voip avec votre bundleid pour l'envoi d'une notification push voip (par exemple: bundleid.voip).
Voici un exemple pratique de notification push par VoIP:
<?php
$token = $_REQUEST['tok'];
if (!defined('CURL_HTTP_VERSION_2_0')) {
define('CURL_HTTP_VERSION_2_0', 3);
}
// open connection
$http2ch = curl_init();
curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// send Push
$Apple_cert = 'certificate_name.pem';
$message = '{"aps":{"action":"message","title":"your_title","body":"your_message_body"}}';
$http2_server = 'https://api.development.Push.Apple.com'; // or 'api.Push.Apple.com' if production
$app_bundle_id = 'your bundle id';
$status = sendHTTP2Push($http2ch, $http2_server, $Apple_cert, $app_bundle_id, $message, $token);
echo $status;
// close connection
curl_close($http2ch);
function sendHTTP2Push($http2ch, $http2_server, $Apple_cert, $app_bundle_id, $message, $token)
{
// url (endpoint)
$url = "{$http2_server}/3/device/{$token}";
$cert = realpath($Apple_cert);
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
"User-Agent: My Sender"
);
curl_setopt_array($http2ch, array(
CURLOPT_URL => $url,
CURLOPT_PORT => 443,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSLCERT => $cert,
CURLOPT_HEADER => 1
));
$result = curl_exec($http2ch);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($http2ch));
}
// get response
$status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
if($status=="200")
echo "SENT|NA";
else
echo "FAILED|$status";
}
?>