Соединение с APNS для iPhone Using Python

Сделайте:

NSData *data = [yourString dataUsingEncoding:NSUTF8StringEncoding];

, затем смело переходите к NSJSONSerialization:JSONObjectWithData.


Исправление к ответу относительно терминатора NULL

После комментариев, официальной документации и проверок этот ответ был обновлен относительно удаления предполагаемого терминатора NULL:

  1. Как задокументировано в dataUsingEncoding: :

    Возвращаемое значение

    Результат вызова dataUsingEncoding:allowLossyConversion: с NO как второй аргумент

  2. Как описано в getCString: maxLength: encoding: и cStringUsingEncoding: :

    отметим, что данные, возвращаемые dataUsingEncoding:allowLossyConversion:, не являются строгой C-строкой, поскольку они не имеют терминатора NULL

12
задан elioty 23 July 2009 в 15:57
поделиться

5 ответов

Недавно я сделал это с помощью Django - http://leecutsco.de/2009/07/14/push-on-the-iphone/

Может быть полезно? Он не использует никаких дополнительных библиотек, кроме тех, которые уже включены в Python. Не потребуется много времени, чтобы извлечь метод send_message ().

8
ответ дан 2 December 2019 в 21:23
поделиться

Рассматривали ли вы пакет Twisted ? Приведенный ниже код взят из здесь :

from struct import pack
from OpenSSL import SSL
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.ssl import ClientContextFactory

APNS_SERVER_HOSTNAME = "<insert the push hostname from your iPhone developer portal>"
APNS_SERVER_PORT = 2195
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>"
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>"

class APNSClientContextFactory(ClientContextFactory):
    def __init__(self):
        self.ctx = SSL.Context(SSL.SSLv3_METHOD)
        self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE)
        self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE)

    def getContext(self):
        return self.ctx

class APNSProtocol(Protocol):
    def sendMessage(self, deviceToken, payload):
        # notification messages are binary messages in network order
        # using the following format:
        # <1 byte command> <2 bytes length><token> <2 bytes length><payload>
        fmt = "!cH32cH%dc" % len(payload)
        command = 0
        msg = struct.pack(fmt, command, deviceToken,
                          len(payload), payload)
        self.transport.write(msg)

class APNSClientFactory(ClientFactory):
    def buildProtocol(self, addr):
        print "Connected to APNS Server %s:%u" % (addr.host, addr.port)
        return APNSProtocol()

    def clientConnectionLost(self, connector, reason):
        print "Lost connection. Reason: %s" % reason

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed. Reason: %s" % reason

if __name__ == '__main__':
    reactor.connectSSL(APNS_SERVER_HOSTNAME, 
                       APNS_SERVER_PORT,
                       APNSClientFactory(), 
                       APNSClientContextFactory())
    reactor.run()
2
ответ дан 2 December 2019 в 21:23
поделиться

в первоначально опубликованном коде было несколько ошибок, поэтому вот исправленная версия, которая мне подходит.

from struct import pack
from OpenSSL import SSL
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.ssl import ClientContextFactory
import binascii
import struct

APNS_SERVER_HOSTNAME = "gateway.sandbox.push.apple.com"
APNS_SERVER_PORT = 2195
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>"
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>"
DEVICE_TOKEN = "<hexlified device token>"
MESSAGE = '{"aps":{"alert":"twisted test"}}'

class APNSClientContextFactory(ClientContextFactory):
    def __init__(self):
        self.ctx = SSL.Context(SSL.SSLv3_METHOD)
        self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE)
        self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE)

    def getContext(self):
        return self.ctx

class APNSProtocol(Protocol):

    def connectionMade(self):
        print "connection made"
        self.sendMessage(binascii.unhexlify(DEVICE_TOKEN), MESSAGE)
        self.transport.loseConnection()

    def sendMessage(self, deviceToken, payload):
        # notification messages are binary messages in network order
        # using the following format:
        # <1 byte command> <2 bytes length><token> <2 bytes length><payload>
        fmt = "!cH32sH%ds" % len(payload)
        command = '\x00'
        msg = struct.pack(fmt, command, 32, deviceToken,
                          len(payload), payload)
        print "%s: %s" %(binascii.hexlify(deviceToken), binascii.hexlify(msg))
        self.transport.write(msg)

class APNSClientFactory(ClientFactory):
    def buildProtocol(self, addr):
        print "Connected to APNS Server %s:%u" % (addr.host, addr.port)
        return APNSProtocol()

    def clientConnectionLost(self, connector, reason):
        print "Lost connection. Reason: %s" % reason

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed. Reason: %s" % reason

if __name__ == '__main__':
    reactor.connectSSL(APNS_SERVER_HOSTNAME,
                       APNS_SERVER_PORT,
                       APNSClientFactory(),
                       APNSClientContextFactory())
    reactor.run()
2
ответ дан 2 December 2019 в 21:23
поделиться

Я попробовал и APNSWrapper , и код Ли Пекхэма, и не смог заставить его работать под Snow Leopard с Python 2.6. После долгих проб и ошибок он наконец работал с pyOpenSSL .

Я уже написал сообщение с подробностями и фрагментами кода здесь , поэтому я просто порекомендую вас туда.

0
ответ дан 2 December 2019 в 21:23
поделиться

Попробуйте обновить APNSWrapper до последней версии (0.4). Теперь есть встроенная поддержка инструмента командной строки openssl (openssl s_client).

1
ответ дан 2 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: