web-dev-qa-db-fra.com

Apple APNS (Push notification services) exemple de code

Existe-t-il un exemple de projet montrant comment utiliser APNS sur l'iPhone et comment configurer les choses? Je regarde actuellement la documentation mais ce serait bien d'avoir du code de travail à séparer et de voir comment tout cela fonctionne ensemble?

Je n'arrive pas à trouver quoi que ce soit en utilisant Google ou dans le centre de développement iPhone.

51
froh42

Le pire aspect de la configuration du service de notification Push est le provisionnement. La principale pierre d'achoppement que j'ai rencontrée est qu'il y a un certificat et une clé dans le fichier .cer que vous téléchargez sur le site d'Apple, j'ai écrit un service système en C # qui a envoyé des notifications et les connexions ont continué à échouer parce que j'avais exporté le certificat et non la clé.

Je ne me souviens pas qui a écrit cela à l'origine, voici un peu de code en python qui m'a aidé lorsque j'ai testé le service de notification pour la première fois. Je l'aime parce qu'il est très simple et fonctionne bien pendant les tests.

import socket, ssl, json, struct

# device token returned when the iPhone application
# registers to receive alerts

deviceToken = 'XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX' 

thePayLoad = {
     'aps': {
          'alert':'Oh no! Server\'s Down!',
          'sound':'k1DiveAlarm.caf',
          'badge':42,
          },
     'test_data': { 'foo': 'bar' },
     }

# Certificate issued by Apple and converted to .pem format with openSSL
# Per Apple's Push Notification Guide (end of chapter 3), first export the cert in p12 format
# openssl pkcs12 -in cert.p12 -out cert.pem -nodes 
#   when prompted "Enter Import Password:" hit return
#
theCertfile = 'cert.pem'
# 
theHost = ( 'gateway.sandbox.Push.Apple.com', 2195 )

# 
data = json.dumps( thePayLoad )

# Clear out spaces in the device token and convert to hex
deviceToken = deviceToken.replace(' ','')
byteToken = bytes.fromhex( deviceToken ) # Python 3
# byteToken = deviceToken.decode('hex') # Python 2

theFormat = '!BH32sH%ds' % len(data)
theNotification = struct.pack( theFormat, 0, 32, byteToken, len(data), data )

# Create our connection using the certfile saved locally
ssl_sock = ssl.wrap_socket( socket.socket( socket.AF_INET, socket.SOCK_STREAM ), certfile = theCertfile )
ssl_sock.connect( theHost )

# Write out our data
ssl_sock.write( theNotification )

# Close the connection -- Apple would prefer that we keep
# a connection open and Push data as needed.
ssl_sock.close()

Il y a aussi un Rails gem appelé apn_on_Rails qui semble fonctionner assez bien si vous développez une application Rails, je l'ai vu aujourd'hui et j'ai pu envoyer des notifications de la console.

Du côté de l'iPhone, vous aurez juste besoin d'appeler ce qui suit pour vous inscrire à tous les types de notifications:

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

Pour recevoir le jeton d'appareil, vous devez implémenter les méthodes de délégation suivantes:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

Pendant les tests, vous pouvez simplement lancer le deviceToken sur la console avec NSLog, puis le coller dans le script python ci-dessus, en production, vous devrez évidemment configurer une méthode pour obtenir le jeton sur votre les serveurs.

De plus, en production, vous devrez interroger le service de commentaires d'Apple et supprimer les jetons d'appareil des utilisateurs qui ont supprimé votre application.

59
jessecurry

Un bon point de départ est rban Airship . Vous pouvez créer un compte de base gratuit qui fera tout le travail côté serveur d'envoi de notifications Push aux serveurs d'Apple. Ils font également un excellent travail pour vous guider à travers toutes les étapes nécessaires pour que votre application fonctionne avec leur service, et ont un excellent exemple de code qui montre comment enregistrer votre application pour les notifications.

Je n'ai aucune autre affiliation avec eux que d'être un utilisateur heureux de leur service.

15
Scott K.

Au cas où cela aiderait, j'ai écrit une bibliothèque Python, PyAPNs, pour interagir avec le service de notification push côté serveur:

http://github.com/simonwhitaker/PyAPNs

14
Simon Whitaker

http://blog.boxedice.com/2009/07/10/how-to-build-an-Apple-Push-notification-provider-server-tutorial/

Celui-ci m'a beaucoup aidé à créer du code côté fournisseur sur un serveur Linux avec PHP.

12
Mladen

Il n'y a vraiment pas beaucoup de code à écrire du côté iPhone. Vous devez obtenir le jeton unique de l'iPhone ou de l'iPod Touch, puis relayer ce jeton sur votre serveur. L'obtention du jeton nécessite un appel à UIApplication, mais il n'y a aucun moyen prédéfini de l'obtenir sur votre serveur. Une de mes applications exécute un HTTP POST vers un script PHP qui place le jeton dans une base de données.

Si vous êtes curieux au sujet de l'approvisionnement et de la configuration des certificats, etc ..., vous pouvez consulter le Apple Push Notification Service Programming Guide.

5
Ben Gotow

Je sais que c'est une très vieille question et a reçu de nombreuses réponses mais j'ai trouvé le tutoriel de Rey Wenderlich très utile et je voulais le partager pour les débutants APNS. C'est très utile et très facile à comprendre.

4
Aditya

Je sais que c'était en retard, mais vous devriez voir MonoPush project. Il semble qu'ils fourniront une nouvelle façon d'intégrer Push ainsi que des statistiques détaillées, y compris des statistiques sur la carte.

3
fyasar

Regardez dans les forums du centre de développement iPhone, supposément il y a beaucoup d'exemples de code côté serveur pour parler au serveur Push d'Apple.

Voici une version testée php5 du script de test de jessecurry. Il utilise le ' format de message amélioré ' et essaie de détecter et d'afficher les erreurs d'Apple. Cela pourrait donner une indication sur ce qui ne va pas avec vos messages.

// Settings
$deviceToken = 'xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx';
$apnsCert = 'apns-dev.pem';
$apnsHost = 'gateway.sandbox.Push.Apple.com';
$apnsPort = 2195;

// Prepare payload
$payload = 
array(
    'aps' => array(
        'alert' => 'Hi, this is an alert!',
        'badge' => 8
    )
);
$payload = json_encode($payload);
print($payload . "\n");

// Connect to Apple Push Notification server
$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) {
    die('Error creating ssl socket');
}
// Don't block on reading from the socket
stream_set_blocking ($apns, 0);

// Send payload in enhanced message format ( http://developer.Apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//Apple_ref/doc/uid/TP40008194-CH101-SW1 )
$apnsMessage = 
    // Command "1"
    chr(1)
    // Identifier "88"
    . pack('N', 88)
    // Expiry "tomorrow"
    . pack('N', time() + 86400)
    // Token length
    . chr(0) . chr(32) 
    // Device token
    . pack('H*', str_replace(' ', '', $deviceToken)) 
    // Payload length
    . chr(0) . chr(strlen($payload)) 
    // Actual payload
    . $payload . $payload;
fwrite($apns, $apnsMessage);

// Pause for half a second to check if there were any errors during the last seconds of sending.
usleep(500000); 

checkAppleErrorResponse($apns);

// Close connection -- Apple would prefer that we keep
// a connection open and Push data as needed.
fclose($apns);

function checkAppleErrorResponse($apns)
{
    $responseBinary = fread($apns, 6);
    if ($responseBinary !== false && strlen($responseBinary) == 6)
    {
        print(
            "\n"
            .'Error message recieved from Apple.'."\n"
            .'For the meaning, refer to: "Provider Communication with Apple Push Notification Service"'."\n"
        );
        $response = unpack('Ccommand/Cstatus_code/Nidentifier', $responseBinary);
        var_dump($response);
    }
}
1
Simon Epskamp

Essayez le projet NWPusher sur GitHub. Il fournit des applications OS X et iOS pour envoyer des notifications Push manuellement, ou vous pouvez utiliser directement la bibliothèque Objective-C incluse.

1
leo