Yosemite has Python 2.7.6 built in but for many reasons (one of them is sudo) we prefer a clean up-to-date install.

pytInstall Python (on OS X Yosemite)

Yosemite has Python 2.7.6 built in but for many reasons (one of them is sudo) we prefer a clean up-to-date install.

brew install python

Make sure the newly installed Python is in the path:

vi ~/.zshrc
PATH=$PATH:/usr/local:/usr/local/bin: # Add Python to PATH
source ~/.zshrc

Double check we have the latest version:

python -V

Virtual environments is a must to keep all the dependencies in check:

pip install virtualenv

Create a new virtual environment called pyenv and activate it:

virtualenv pyenv
source pyenv/bin/activate

Install Python APN library:

pip install apns

Now it is a good idea to make our installation easily repeatable:

pip freeze > requirements.txt

Later we can restore all the required libraries:

pip install -r requirements.txt

Or even update them all:

pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs pip install -U

From developer.apple.com download “APNs Production iOS” certificate, aps_production.cer.

Now, this is the tricky part. We have to convert it to a .p12 certificate.

To do that, double-click on the certificate so that it is added to the keychain.

Open “Keychan Access” and right-click on the certificate to export it as .p12 certificate.

It is very important to export the certificate and not the private key!

Lets export it into a PEM certificate that either contains both the private key and the certificate:

openssl pkcs12 -in aps_production.p12 -out aps_production_olinguito.pem -nodes

Or into two separate files, one with the key and the other one with the certificate (preferred method):

openssl pkcs12 -nocerts -in aps_production.p12 -out aps_prod_key.pem -nodes
openssl pkcs12 -nokeys -in aps_production.p12 -out aps_prod_cert.pem -nodes

A very simple script to test our notifications:

import time
from apns import APNs, Frame, Payload

apns = APNs(use_sandbox=False, cert_file='aps_prod_cert.pem', key_file='aps_prod_key.pem', enhanced=True)

# Send a notification
token_hex = 'dd6b492f92546f8a02d9a36e689b4be28b0c663db7b6c278379866a7e1behell'
payload = Payload(alert="Hello World!", sound="default", badge=1)
apns.gateway_server.send_notification(token_hex, payload)

Welcome to The infinite monkey theorem

Somewhere a monkey just typed Shakespeare in TypeScript. Be the first to read the masterpieces (and the hilarious misfires) landing on the blog.

Subscribe to The infinite monkey theorem

We fling fresh posts—no banana peels attached—straight to your inbox.