I am trying to implement the new 'Command 2' push notification in Java and cannot have it push multiple alerts. First alert is pushed successfully. Please help if you can spot any issue on this code
for (DeviceApps deviceApps : deviceAppsList) {
outputStream.write(getByteArray(deviceApps, pushAlert));
}
private byte[] getByteArray(DeviceApps deviceApps, PushAlert pushAlert) {
ByteArrayOutputStream dataBao = new ByteArrayOutputStream();
// Write the TokenLength as a 16bits unsigned int, in big endian
dataBao.write((byte)1);
dataBao.write(intTo2ByteArray(32));
dataBao.write(deviceTokenAsBytes);
// Write the PayloadLength as a 16bits unsigned int, in big endian
dataBao.write((byte)2);
dataBao.write(intTo2ByteArray(payLoadAsBytes.length));
dataBao.write(payLoadAsBytes);
// 4 bytes. Notification identifier
dataBao.write((byte)3);
dataBao.write(intTo2ByteArray(4));
dataBao.write(intTo4ByteArray(random.nextInt()));
// 4 bytes Expiration date
dataBao.write((byte)4);
dataBao.write(intTo2ByteArray(4));
dataBao.write(intTo4ByteArray(pushAlert.getUtcExpireTime()));
LOG.error("UtcExpireTime="+ pushAlert.getUtcExpireTime());
// 1 bytes Priority
dataBao.write((byte)5);
dataBao.write(intTo2ByteArray(1));
dataBao.write((byte)10);
//Frame Info
bao = new ByteArrayOutputStream();
bao.write((byte)2);
byte [] data = dataBao.toByteArray();
bao.write(intTo4ByteArray(data.length));
LOG.error(" data.length "+data.length);
bao.write(data);
return bao.toByteArray();
}
Support Methods
private static final byte[] intTo4ByteArray(int value) {
return ByteBuffer.allocate(4).putInt(value).array();
}
private static final byte[] intTo2ByteArray(int value) {
int s1 = (value & 0xFF00) >> 8;
int s2 = value & 0xFF;
return new byte[] { (byte) s1, (byte) s2 };
}
Since you are getting back a an error code from APNS, the connection should be dropped at that point and APNS will ignore everything after the error. When you receive an error back, the identifier is the identifier you are currently using a random number for.
There's no easy solution here -- you have to rearchitect what you have so that when you receive the error, you can figure out everything after that point and resend -- I'd recommend using a sequential number for the Identifier and then storing the packets in a queue that you purge periodically (you have to keep them around for say 30 seconds to guarantee that Apple Accepted them).
It looks like you are writing a single notification to
bao
, so why do you expect it to push multiple alerts? If you want to push multiple alerts, you have to repeat that sequence of bytes that you write intobao
multiple times.The command 2 and the frame data length applies to each message. If you send multiple messages in one connection, then for each message: send command 2, the message's frame data length, and the 5 parts (token, payload, id, expiry, priority)