1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.mobile.push.apns">
<title>Zend_Mobile_Push_Apns</title>
<para>
<classname>Zend_Mobile_Push_Apns</classname> provides the ability to
send push notifications to <acronym>APNS</acronym> generally in
conjunction with <classname>Zend_Mobile_Push_Message_Apns</classname>;
however there is a case when it would not be utilized is when getting
feedback from the APNS server.
</para>
<sect2 id="zend.mobile.push.apns.server">
<title>Pushing Messages</title>
<note>
<para>Prior to pushing messages; you must follow the
<ulink
url="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ProvisioningDevelopment/ProvisioningDevelopment.html">provisioning and deployment steps outlined by Apple</ulink>.</para>
</note>
<para>
When implementing APNS; you have a few components that
you will utilize. <classname>Zend_Mobile_Push_Apns</classname>
which contains the server components and
<classname>Zend_Mobile_Push_Message_Apns</classname> which contains
the message that you would like to send. Generally when sending
push notifications to Apple you should do so in a batch.
</para>
<para>
The actual implementation of the code is fairly minimal; however,
considerations to error handling must be taken.
</para>
<programlisting language="php"><![CDATA[
$message = new Zend_Mobile_Push_Message_Apns();
$message->setAlert('Zend Mobile Push Example');
$message->setBadge(1);
$message->setSound('default');
$message->setId(time());
$message->setToken('ABCDEF0123456789');
$apns = new Zend_Mobile_Push_Apns();
$apns->setCertificate('/path/to/provisioning-certificate.pem');
// if you have a passphrase on your certificate:
// $apns->setCertificatePassphrase('foobar');
try {
$apns->connect(Zend_Mobile_Push_Apns::SERVER_SANDBOX_URI);
} catch (Zend_Mobile_Push_Exception_ServerUnavailable $e) {
// you can either attempt to reconnect here or try again later
exit(1);
} catch (Zend_Mobile_Push_Exception $e) {
echo 'APNS Connection Error:' . $e->getMessage();
exit(1);
}
try {
$apns->send($message);
} catch (Zend_Mobile_Push_Exception_InvalidToken $e) {
// you would likely want to remove the token from being sent to again
echo $e->getMessage();
} catch (Zend_Mobile_Push_Exception $e) {
// all other exceptions only require action to be sent
echo $e->getMessage();
}
$apns->close();
]]></programlisting>
<table id="zend.mobile.push.apns.server.exceptions">
<title>Exceptions and Remediation Techniques</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<thead>
<row>
<entry>Exception</entry>
<entry>Meaning</entry>
<entry>Handling</entry>
</row>
</thead>
<tbody>
<row>
<entry>Zend_Mobile_Push_Exception</entry>
<entry>These types of exceptions are more generic in nature
and are thrown either from APNS or internally on input
validation</entry>
<entry>Read the message and determine remediation steps.</entry>
</row>
<row>
<entry>Zend_Mobile_Push_Exception_InvalidPayload</entry>
<entry>Generally the payload will not throw an exception
unless the size of the payload is too large or it is missing
required content.</entry>
<entry>Check the size of the payload is within the
requirements of APNS</entry>
</row>
<row>
<entry>Zend_Mobile_Push_Exception_InvalidToken</entry>
<entry>Any form of an invalid token will be if the token is
no longer registered; you are missing a token or it is in an
invalid format.</entry>
<entry>You should remove the token and not attempt to send
to it again.</entry>
</row>
<row>
<entry>Zend_Mobile_Push_Exception_InvalidTopic</entry>
<entry>An invalid topic simply means that the message id was
too long or not an integer.</entry>
<entry>Ensure that the message ID is an integer.</entry>
</row>
</tbody>
</tgroup>
</table>
<warning>
<para>
When sending in batches and you are sending a large amount of push
notifications out; you should ensure to usleep from time to time. This
will ensure that your messages will be delivered and APNS will not simply
hang up on you.
</para>
</warning>
</sect2>
<sect2 id="zend.mobile.push.apns.feedback">
<title>Getting Feedback</title>
<para>
APNS has a feedback service that you <emphasis>must</emphasis>
listen to. Apple states that they monitor providers to ensure that they
are listening to this service.
</para>
<para>
The feedback service simply returns an array of device tokens and
the time. You can use the time to ensure that the device has not
re-registered for push notifications since the last send.
</para>
<programlisting language="php"><![CDATA[
$apns = new Zend_Mobile_Push_Apns();
$apns->setCertificate('/path/to/provisioning-certificate.pem');
try {
$apns->connect(Zend_Mobile_Push_Apns::SERVER_FEEDBACK_SANDBOX_URI);
} catch (Zend_Mobile_Push_Exception_ServerUnavailable $e) {
// you can either attempt to reconnect here or try again later
exit(1);
} catch (Zend_Mobile_Push_Exception $e) {
echo 'APNS Connection Error:' . $e->getMessage();
exit(1);
}
$tokens = $apns->feedback();
while(list($token, $time) = each($tokens)) {
echo $time . "\t" . $token . PHP_EOL;
}
$apns->close();
]]></programlisting>
</sect2>
<sect2 id="zend.mobile.push.apns.message">
<title>Advanced Messages</title>
<para>
APNS provides the ability for sending more advanced messages; for
instance the examples above show the most basic implementation of a
message. <classname>Zend_Mobile_Push_Message_Apns</classname>
allows you to do far more advanced messaging outlined below.
</para>
<sect3 id="zend.mobile.push.apns.message.alerts">
<title>Alerts</title>
<para>
Alerts can contain anything from a simple body message to having an
action key and a launch image (iOS 4). You may only want to provide
an action key when only a confirmation is necessary OR you are
looking to localize the button with non-standard text (aka not
"View").
</para>
<para>
The following code example shows alerts from the <ulink
url="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html">APNS
payload examples</ulink>.
</para>
<programlisting language="php"><![CDATA[
$message = new Zend_Mobile_Push_Message_Apns();
// message with different button
$message->setAlert('Bob wants to play poker', 'PLAY');
// message using apps localized strings w/ string replacements
$message->setAlert(null, null, 'GAME_PLAY_REQUEST_FORMAT', array('Jenna', 'Frank'));
]]></programlisting>
</sect3>
<sect3 id="zend.mobile.push.apns.message.custom-data">
<title>Custom Data</title>
<para>
You can send your app custom data which allows you to make decisions
based on the notifications; such as synchronizing data.
</para>
<programlisting language="php"><![CDATA[
$message = new Zend_Mobile_Push_Message_Apns();
$message->addCustomData('foo', 'bar');
$message->addCustomData('foo', array('bar' => 1));
$message->addCustomData('bar', 'foo');
]]></programlisting>
<warning>
<para>
You may not use a custom key of 'aps' as it is reserved by Apple and
leveraged for the main push data.
</para>
</warning>
</sect3>
</sect2>
</sect1>
|