Must I use HTTP/2.0 to send Apple Push Notifications? May I use libcurl?

As it stands right now, Apple is still supporting its legacy v2 (binary) API, which works over HTTPS, so HTTP/2 is only required if you want to use the latest API.

The legacy API is documented in an appendix, but honestly, compared to the HTTP/2 API, it is so horrible that I could not recommend using it.

I can say for sure that the legacy API is supported because I have production code that is using it right now (this is also why I can say the API is horrible, and I am busy migrating it to HTTP/2).


OK after a good deal of time I finally found the answer. Yes, HTTP/2 is required to use APNS.

It comes down to a single line in the APNS docs that says

APNs requires the use of HPACK (header compression for HTTP/2), which prevents repeated header keys and values.

which would imply that HTTP/2 is a required part of the protocol.


A sample script using curl to send http2 push message. Given that you have the authentication key from dev site and your version of curl is compiled with http2 support. The p8 file should be in the same folder of the script say apns.sh file. Run>bash apns.sh

#!/bin/bash

deviceToken=96951ABACECA47F34C2F93D8E58591054E6F2B42691B4EADA6935C19A107A524

authKey="./AuthKey_SLDFJSDLB.p8"
authKeyId=SLDFJSDLB
teamId=ABCDET
bundleId=com.mycompany.myapp
endpoint=https://api.development.push.apple.com
apns_collapse_id="score_update"

read -r -d '' payload <<-'EOF'
{
   "aps": {
      "badge": 2,
      "category": "mycategory",
      "alert": {
         "title": "my title",
         "subtitle": "my subtitle",
         "body": "my body text message 103"
      }
   },
   "custom": {
      "mykey": "myvalue"
   }
}
EOF

# --------------------------------------------------------------------------

base64() {
   openssl base64 -e -A | tr -- '+/' '-_' | tr -d =
}

sign() {
   printf "$1"| openssl dgst -binary -sha256 -sign "$authKey" | base64
}

time=$(date +%s)
header=$(printf '{ "alg": "ES256", "kid": "%s" }' "$authKeyId" | base64)
claims=$(printf '{ "iss": "%s", "iat": %d }' "$teamId" "$time" | base64)
jwt="$header.$claims.$(sign $header.$claims)"

curl --verbose \
   --header "content-type: application/json" \
   --header "authorization: bearer $jwt" \
   --header "apns-topic: $bundleId" \
   --header "apns-collapse-id: $apns_collapse_id"\
   --http2 \
   --data "$payload" \
   $endpoint/3/device/$deviceToken