YaBCK
YaBCK

Reputation: 3029

iOS application push notifications

We have an application built in PHP that sends out push notifications to both Android and iOS. Our problem is there are some device ids for iOS that seem to completely halt the sending of the all other iOS push notifications in our script, they even say that they have been sent without errors but it stops all notifications in the loop afterwards.

If we then remove the offending device id from our database the sending script works for all devices after the offending device. It is very strange and cant seem to figure out why.

Does anyone have any experience with this? Is it to do with sending to a device ID that doesnt exist anymore will stop apple from completing our script on that specific connection?

Here is our sending script in PHP (this works for all devices apart from the odd rogue device id):

    $tHost = 'gateway.push.apple.com';
    $tPort = 2195;
    $tCert = "path_to_our_cert.pem";
    $tPassphrase = 'passphrase';

    $tAlert = $this->title; //assign a title
    $tBadge = 8;
    $tSound = 'default';
    $tPayload = $this->body_plain; //assign a body

            // Create the message content that is to be sent to the device.
    $tBody['aps'] = array ('alert' => $tAlert,'badge' => $tBadge,'sound' => $tSound,);
    $tBody ['payload'] = $tPayload;
    $tBody = json_encode ($tBody);

    $tContext = stream_context_create ();
    stream_context_set_option ($tContext, 'ssl', 'local_cert', $tCert);
    stream_context_set_option ($tContext, 'ssl', 'passphrase', $tPassphrase);
    $tSocket = stream_socket_client ('ssl://'.$tHost.':'.$tPort, $error, $errstr, 30, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $tContext);   

    if (!$tSocket) exit ("APNS Connection Failed: $error $errstr" . PHP_EOL);
    //Loop through all devices to send
    foreach($this->device->devices as $item){
        if($item->os != "iOS") continue;                
        if(session::getAdministratorStaffSchoolID() != $item->school_id) continue;
        $tToken = $item->device_id;//assign the device id
        $tMsg = chr (0) . chr (0) . chr (32) . pack ('H*', $tToken) . pack ('n', strlen ($tBody)) . $tBody;
            $tResult = fwrite ($tSocket, $tMsg, strlen ($tMsg));
    }

    fclose ($tSocket);

Does anyone have any ideas regarding this?

Many thanks

Upvotes: 1

Views: 394

Answers (2)

BertKlinger
BertKlinger

Reputation: 91

AFAIK APNs will close the connection as soon as any error occurs (invalid device token, malformed payload, etc.). Your code that sends out Push needs to be prepared to recover from this situation, reconnect and then restart the work.

Take a look at the 3rdParty libraries out there to execute this job for you. You'll rely on the community work.

I can referral Pushy which is written in Java. I have used it in 2 different projects and I can say it works fine and it's an very active project (a lot of discussions and updates there).

I don't know any of them using PHP, but probably there is one

Upvotes: 0

ncke
ncke

Reputation: 1094

So, just a thought, but you're using the legacy format to send the notification:

$tMsg = chr (0) . chr (0) . chr (32) . pack ('H*', $tToken) . pack ('n', strlen ($tBody)) . $tBody;

And:

Error response. With the legacy format, if you send a notification packet that is malformed in some way—for example, the payload exceeds the stipulated limit—APNs responds by severing the connection. It gives no indication why it rejected the notification. The enhanced format lets a provider tag a notification with an arbitrary identifier. If there is an error, APNs returns a packet that associates an error code with the identifier. This response enables the provider to locate and correct the malformed notification.

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Appendixes/LegacyFormat.html

So maybe APNS is just dropping the connection on you? That's why all the remaining notifications actually don't get through. Take a closer look at those payloads. And might be a good time to move to the new format.

Upvotes: 1

Related Questions