Push Notifications Tutorial: Getting Started

I struggled with this. I was getting the following:

Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failedā€¦

At some point in my searching the Internet I ran across the following suggestion ā€“ add this line of code:

stream_context_set_option($ctx, ā€˜sslā€™, ā€˜verify_peerā€™, false);

This worked, but it deletes the purpose of SSL because it disables the script from verifying that it is talking with APNS. I didnā€™t want that as my long term solution, So I kept searching and ran across this post:

[ios - Push Notification in PHP using PEM file - Stack Overflow]

Sandy D.'s solution worked great!

Hey Jack,

Thanks for the wonderful tutorial. It was very helpful indeed.
However, I have a different kind of problem when handling push notification. In my project, we have a number of view controllers which we need to display depending on the type of data received in the notification. For this, we have created a class which parses the data and has a switch case to which initializes the controller from the push notification and pushes it on the stack. But the switch case causes the app to be very brittle. A small change here or there and the push stop working and has lately become highly unmaintainable. I was wondering if you had a cleaner way to handle this kind of scenario.

1 Like

I advise you to use this great tool that allows to send Push Notifications : NWPusher

You can but keep in mind that the payload size is limited to 2 kilobytes. I suggest you send the link to the image in the push notificationā€™s payload then you download it when you should respond to the push notification.

Would it be possible to get the userā€™s location in a silent alert and send that location to the server?
Iā€™m sending a notification with ā€œcontent-availableā€: 1 and starting a location manager but the locationManager:(CLLocationManager *)manager didUpdateLocations: does not get called in the back ground. Iā€™m trying to avoid tracking location constantly by requesting it only when itā€™s needed via a push notification.

Please use the following command to build the .pem file .

openssl pkcs12 -in M8CardPushProd.p12 -out ckp.pem -nodes -clcerts

Also do not for get to add the php code line below to your php push test file.
stream_context_set_option($ctx, ā€˜sslā€™, ā€˜verify_peerā€™, false);

Any chance youā€™ll be updating this for Swift 3 anytime soon?

ATTENTION MAC SIERRA USERS:
You will not be able to complete this tutorial unless you head the (currently second to top) answer on stack: ios - APNs push notification with macOS Sierra - Stack Overflow

Basically Sierra updated php to 2.6, so you must replaced:

$streamContext = stream_context_create();

with:

$streamContext = stream_context_create([
            'ssl' => [
                'verify_peer'      => false,
                'verify_peer_name' => false
            ]
        ]);

or else you get this error:

Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /Users/USERNAME/APNS/newPush.php on line 24

Warning: stream_socket_client(): Failed to enable crypto in /Users/USERNAME APNS/newPush.php on line 24

Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/USERNAME/APNS/newPush.php on line 24
Failed to connect: 0

Your solution worked like a charm.
Great !!! Thanks !!!

Hi Jack,

This was a great tutorial, and what I use for my reference in building and testing APNS. I also created some java server code to push and a nice web service in the app to upload the device token back to my server.

Unfortunately, so much has changed with IOS 10. The new API is great. Will you by any chance, be upgrading the tutorial in the near future? I also noticed that ā€œIOS 10 By Tutorialsā€ references this tutorial. For me, it was a good way to learn the infrastructure and APIā€™s. A lot of the IOS 10 info is fragmented.

Thanks
Vinnie

Iā€™ve implemented the recommendations above, but it seems it doesnā€™t work since IOS10 release.
Thereā€™s a new feature called ā€œAPNs authentication tokensā€ which requires to generate a certificate dedicated for thisā€¦and use the HTTP/2 protocol.
Can someone really ensure the ā€œoldā€ way as described above still works for IOS 10 device (Iā€™m testing it on iPhone7 and IOS10) ?
Iā€™ve tested the following command line: openssl s_client -CAfile entrust_2048_ca.cer -connect gateway.sandbox.push.apple.com:2195 -cert mobileappdev.pem -key mobileappde
v.pem.
It gives the following answer: Verify return code: 0 (ok)
Even if in the middle of the test the following appears.
17576:error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error:.\ssl\s3_pkt.c:1300:SSL alert number 80
17576:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:.\ssl\s23_lib.c:177:

When I execute ā€œnewspush.phpā€ I get the following error:
PHP Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error: 14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error in /usr/local/newspush.php on line 32
PHP Warning: stream_socket_client(): Failed to enable crypto in /usr/local/newspush.php on line 32
PHP Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /usr/local/newspush.php on line 32
Failed to connect: 0

Thanks for your precious help !

Ludo

Reply to myself: I finally discovered Iā€™ve selected the wrong certificate :relaxed:
So, everything works.

Hi all, Iā€™m hoping some one can help me with this.

  • we have notifications as part of our app and store the device token once the user registers an account and log in.
  • we are currently only keeping the latest device token for a specific log in account.Hence if another user in the company uses the same account (this happens) to log in, the previous user doesnā€™t receive any notifications when he/she logs in.
  • whatā€™s the right way to handle these device tokens to make sure that all users logged in to an account, irrespective of device, get a notification.
  • If we donā€™t delete the device token, is there a risk of getting duplicate notifications, when the user installs another version of the app later on?

Appreciate inputs!
PV

Hi all,

I have this weird issue with my parking provider in my hometown.

Itā€™s membership allows you to register a parking action in the streets by entering the code of the parking area. You can do that with their smartphone app. You can get (push)notifications (e.g. every hour) that you are still registered, so you wonā€™t forget to sign off when you leave again.

My wife has also the app and uses a different car.

We login the app by using each our unique telephone number.

However, when I register a parking action with te app on my phone, the notifications are sent to my wifeā€™s phone.

In the past we used both one account, but the parking provider changed this by allowing multiple users and multiple cars on the same account.

I addressed this issue to my parking provider does not seem capable of solving this.

Where could this go wrong in the notification chain?

Kind regards, DerRudy

FYI for anyone working with this tutorial trying to use ā€œcontent-availableā€ the code above doesnā€™t work properly, at least for me, using Swift 3 and Xcode 8.1. The conversion from string to number fails. I just replaced this:

if (aps[ā€œcontent-availableā€] as? NSString)?.integerValue == 1 {

with this:

if aps[ā€œcontent-availableā€] as? NSNumber == 1 {

to get it to work.

Iā€™ve fixed the same error by puting my .pem file renamed in ck.pem next to the PHP script.

Got this working on my first attempt (as a non developer, that in itself is an achievement).

Couple of things:

 {
  "aps":
  {
    "alert": "Breaking News!",
    "sound": "default"
    "link_url" : "https://raywenderlich.com,
  }
}

Appears to have a , instead of a "

Secondly, my iOS 10 device, whilst working with simpler notifications such as

{"aps":{"alert":"Hello from APNs Tester.","badge":"1"}}

or

{"aps" : {
"alert" : {
 "title" : "Introduction to Notifications",
 "subtitle" : "Session 707",
 "body" : "Woah! These new notifications look amazing! Donā€™t you agree?"
 },
 "badge" : 1 },
 }

doesnā€™t appear to work with anything more exotic. Custom buttons, for example, and the above quoted URL example. Ideas? Iā€™m using APN Tester to push

I am getting error-

Warning: stream_socket_client(): Failed to enable crypto in /Users/Desktop/contentpush.php on line 24

Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in /Users/Desktop/contentpush.php on line 24
Failed to connect: 0

on mac serra, production environment.

I changed $ctx = stream_context_create();
with
$ctx = stream_context_create([
ā€˜sslā€™ => [
ā€˜verify_peerā€™ => false,
ā€˜verify_peer_nameā€™ => false
]
]);
as someone did comment.
But getting same error.

Hey thanks for the amazing tutorial. Iā€™m facing one issue though. If the app is killed and then a notification arrives with actions, if :

  1. I click on notification it will open the app using launchoptions.
  2. But if I select an action it is killing the app.

Please help on the 2nd point.

i had been receiving success message on push notification for apn but i am unable to get notification on phone can somebody help me for this . using laravel for push notification