Project S - Day 3: Coding the back-end to send Push Notifications to our App!steemCreated with Sketch.

in #steem7 years ago

In my previous blog, Project S - Day 2, I talked about iOS development and Push Notifications.
Today, I'm going to talk about connecting our primitive back-end to the APNs (Apple Push Notification services) to send some test notifications to our App-in-the-making.

APNs


If you read my previous blog, you might remember the diagram depicting delivery of a remote notification from a provider to an app. If not, here it is again for completeness' sake:
APNs Overview
©Apple

Communication between the app/device and the APNs is automatically handled by Apple's servers. The only thing we need to do, is to register the app with the APNs. Once that is done, the APNs will send back a unique device token to the app. We need this token on the server side (Provider), to be able to send a notification to the device. You can think of it as an unique address for that device.

Connecting


On the Provider side, things become a little more complicated. First we need to connect to the APNs somehow. This can be done with a so called HTTP/2 POST-request. It's similar to how your browser sends a login-form to the website's server you want to login to. Authentication is done with a certificate, which proves to the APNs that the Provider is allowed to connect. When the connection is successful the Provider sends the actual notification message to the APNs, also including the device token so it knows to what device it should forward it.

NOTE:
There is also the option of authenticating with an app token in stead of a certificate. This token is then used to sign an authentication message.

Sending Push Notifications


OK, so our goal today is to send push notifications from our Python code. Let's see how far we get.

First off, we need the push notifications certificate from our keychain. I exported it to a .p12 file (binary) and then used openssl to convert it to a plain-text version (.pem) which includes the public as well as the private key. It is important to not encrypt it with a password. Otherwise it is impossible for the Python program to read it. The command I used was as follows: openssl pkcs12 -in ./iOS-dev.p12 -out ./ios-dev-client-cert.pem -clcerts -nodes.

Next step is to install the python-hyper module to be able to make HTTP/2 requests: pip install hyper

Great! We're all set for a test:

>>> import json
>>> import hyper
>>> from hyper import HTTP20Connection
>>> context = hyper.tls.init_context(cert='/Users/ben/Desktop/ios-dev-client-cert.pem')
<ssl.SSLContext object at 0x100f3ab38>
>>> host = 'api.development.push.apple.com'
>>> port = 443
>>> conn = HTTP20Connection(host, port=port, ssl_context=context)
>>> conn
<hyper.http20.connection.HTTP20Connection object at 0x100f679b0>
>>> url = '/3/device/40a5b1b1d5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdba'
>>> headers = {'apns-expiration': "0", 'apns-priority': "10"}
>>> payload = json.dumps({'aps': { 'alert': "Yo, rukker!" }})
>>> payload
'{"aps": {"alert": "Yo, rukker!"}}'
>>> conn.request('POST', url, body=payload, headers=headers)
5
>>> conn.get_response()
<hyper.http20.response.HTTP20Response object at 0x10152cb38>
>>> _.status
200
>>>

The context object is important here. We tell it to use our personal certificate obtained from Apple. This way, the HTTP20Connection object can authenticate with the APNs. The url contains our unique device token I talked about.

Result!
Screen Shot 2017-09-13 at 22.28.51.png

NOTE:
If you start programming in Python, it is preferable to create a virtual environment. In this way, you can install 3rd party modules and dependencies without breaking other software. Each project gets its own Python environment, with its own modules. See also the Virtualenv documentation for more in-depth info.

NOTE2:
I'm using Python 3.6 for this project. I would advise to use at least Python 3.4 if you start new projects, unless you really have a good reason not to. Installing different Python versions, differs from system to system, so I would recommend you check out the original docs for instructions.

That was it for today. Tomorrow I'll talk a bit about some design considerations.


NEXT UP: Intermezzo


If you support my efforts, please vote, resteem and/or leave your thoughts in the comments.

Your feedback is greatly appreciated! Thanks for reading and STEEM on!

Sort:  

@bennierex This is actually some incredible function!.

Great write-up man, some of it is over my head. But you are a pro!

Don't worry, we'll make a success together.

Coin Marketplace

STEEM 0.18
TRX 0.16
JST 0.029
BTC 76781.75
ETH 3131.82
USDT 1.00
SBD 2.65