IOS7中的静默推送通知无法工作

在 WWDC 2013年的“多任务最新消息”演示文稿中,有一个关于静默推送通知的部分。看起来很直接。根据演示文稿,如果您发送的 APS 有效负载仅将可用内容设置为1,则不会通知用户。

// A. This doesn't work
{
aps: {
content-available: 1
}
}

我的测试表明,这不工作,因为没有推被接收。但是如果我包含 sound 属性但是排除 alert 属性,那么它可以工作(虽然不再是静默的)。

// B. This works
{
aps: {
content-available: 1,
sound: "default"
}
}

但是,如果我更改声音属性以播放无声音频,我可以模拟无声推送。

// C. This works too.
{
aps: {
content-available: 1,
sound: "silence.wav"
}
}

有人知道吗:

  1. 如果这是窃听器呢?
  2. 如果假设 B 或 C 被视为远程通知(而不是需要声音属性的 Silent Push bug)是正确的呢?如果是这样的话,这意味着它不像无声推送那样受到速率限制... ... 苹果可能会解决这个问题。所以我可能不应该依赖它。
  3. 速率限制是多少(N 每 X 秒推一次,等等) ?

先谢谢你。

编辑更多信息

对于 A,应用程序的状态并不重要。从不接收通知。

似乎 B 和 C 只有在将属性和值用引号括起来时才有效,如下所示。

{"aps":{"content-available": 1, "sound":"silent.wav"}}

不管状态如何,通知到达 Application: did ReceiveRemoteNotification: fetchCompletionHandler:

60271 次浏览

I'm seeing the same problem. If I send a push with "content-available":1 and no other attributes set, the notification is never received. When I add any other attributes it works perfectly.

As a temporary work around I'm adding the badge attribute as this doesn't alert the user in any way apart from adding the badge to the icon.

Let me know if you've found a better solution.

This works also and does not play a sound when it arrives:

{
aps = {
"content-available" : 1,
sound : ""
};
}

EDIT

People having this problem may want to check out this link. I have been participating in a thread on Apple's Developer forum that goes over all app states and when silent pushes are received and not received.

Argh! Also pulling my hair out -- this isn't so much an answer as another example of a payload which DOESN'T work. The didReceiveRemoteNotification method is never called, although if the device is sleeping, the alert text IS displayed.

 {"aps":
{  "alert":"alert!",
"sound":"default",
"content-available" : 1},
"content-id":21482,
"apt":"1"
}

"apt" is a custom field we use to indicate the notification type.

Setting 'sound' to 0 worked for me... :)

I have tried setting an empty string as the alert attribute and it also worked:

{
aps =     {
"content-available" = 1;
"alert" = "";
};
}

It seems like APNS is checking for the existence of this attributes for the purpose of validating the push payload. Interestingly, they are not checking the actual content. It seems a little bit hacky though...

So I just came across this issue yesterday, and after trying sending a payload with a sound set to an empty string, it was still causing vibration/sound on the device. Eventually, I stumbled on a blog post from Urban Airship that suggested needing to send:

{ priority: 5 }

in the push notification, which I had never seen. After perusing Apple's docs for push notifications, I stumbled on this page:

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html

Which indicates that priority should be set as "5" or "10", and explains:

The notification’s priority. Provide one of the following values:

10 The push message is sent immediately.

The push notification must trigger an alert, sound, or badge on the device. It is an error to use this priority for a push that contains only the content-available key.

5 The push message is sent at a time that conserves power on the device receiving it.

Ultimately, we were able to get silent push notifications working with a badge count (and I suspect you could even do the same with an alert) with the following format:

    aps =     {
badge = 7;
"content-available" = 1;
priority = 5;
};

This works for me:

{
aps: {
content-available: 1
}
}

Look if you check Background fetch checkbox in Project Capabilities > Background Modes

Priority should be set as one item in binary stream but not in payload json string. Apparently only the latest type 2 format can be used in setting priority as follows:

$token      = chr(1) . pack('n', 32)     . pack('H*', $deviceToken);
$payload    = chr(2) . pack('n', strlen($json)) . $json;
$identifier = chr(3) . pack('n', 4)      . pack('N', $notification);
$expiration = chr(4) . pack('n', 4)      . pack('N', time()+86400);
$priority   = chr(5) . pack('n', 1)      . chr($priority);


$frame_data = $token.$payload.$identifier.$expiration.$priority;
$frame_length = strlen(bin2hex($frame_data))/2;


$msg = chr(2) . pack('N', $frame_length) . $frame_data;

Format types (first byte) for remote notification binary message:

0 - simple (old) 1 - enhanced (old) 2 - latest with more parameters (new)

setting priority to 5 did not work for me, but setting sound or alert to an empty string did cause the notification to be handled as a high priority one

I use the tool-Knuff send my push notification to my device.

It looks like: enter image description here

Then,I tried these example.

They are all work!But you must set the priority 10!

So if you are not use the tool,you also note it.


examples:

  • no alert,no sound

{
"aps":{
"content-available":1,
}
}

  • only alert

{
"aps":{
"content-available":1,
"alert":""
}
}

  • only sound

{
"aps":{
"content-available":1,
"sound":""
}
}

We had the same issue with no Notification being delivered. In our case we were using a silent push to update the badge number. When we set empty strings for alert (body and title) and sound it would work, but if any of the keys were not present it failed. Here is what worked, updating the badge with no sound or alert (log of the resulting userInfo dictionary in didReceiveRemoteNotification)

{
aps =     {
alert =         {
body = "";
title = "";
};
badge = 103;
"content-available" = 1;
sound = "";
};
}