使用Python格式化APNS风格的JSON消息,以便与Amazon SNS一起使用。

19
我正在创建一个iOS应用程序,对于我们的推送通知,我们使用Amazon的Simple Notification Service(SNS)。
SNS非常好用,但是文档相当简洁。我正在使用boto,亚马逊的Python库,并且已经弄清楚如何发送纯文本推送通知:
device_arn = 'MY ENDPOINT ARN GOES HERE'
plain_text_message = 'a plaintext message'
sns.publish(message=plain_text_message,target_arn=device_arn)

然而,文档中并没有说明如何创建苹果推送通知服务(APNS)消息。我需要在推送通知中发送声音和徽章,但无法弄清如何为消息格式化JSON。以下是目前为止我最好的猜测:
message = {'default':'default message', 'message':{'APNS_SANDBOX':{'aps':{'alert':'inner message','sound':'mySound.caf'}}}}
messageJSON = json.dumps(message,ensure_ascii=False)
sns.publish(message=messageJSON,target_arn=device_arn,message_structure='json')

当我运行这段代码时,通知上只显示“默认消息”,这意味着Amazon SNS拒绝了我的消息格式,并显示了“default”。
我该如何正确格式化这个JSON?
2个回答

52
我明白了!原来APNS负载必须作为较大负载内的字符串进行编码 - 这完全有效。
以下是最终的工作代码:
apns_dict = {'aps':{'alert':'inner message','sound':'mySound.caf'}}
apns_string = json.dumps(apns_dict,ensure_ascii=False)
message = {'default':'default message','APNS_SANDBOX':apns_string}
messageJSON = json.dumps(message,ensure_ascii=False)
sns.publish(message=messageJSON,target_arn=device_arn,message_structure='json')

以下是这段代码的步骤说明:

首先,创建用于苹果推送通知服务(APNS)的Python字典:

apns_dict = {'aps':{'alert':'inner message','sound':'mySound.caf'}}

第二步,将该字典转换为JSON格式的字符串:

apns_string = json.dumps(apns_dict,ensure_ascii=False)

第三步,将该字符串放入较大的有效载荷中:

message = {'default':'default message','APNS_SANDBOX':apns_string}

接下来,我们将that编码成自己的JSON格式字符串:

messageJSON = json.dumps(message,ensure_ascii=False)

生成的字符串可以使用boto发布:
sns.publish(message=messageJSON,target_arn=device_arn,message_structure='json')

1
我正在使用C# SDK,除了将APS内容转换为JSON之外,对我来说缺失的关键是设置MessageStructure = "json" ... 一旦我这样做了,一切都很好。谢谢。 - kingdango
我将它适配到了GCM,这是我遇到的问题。效果非常好。以下是我的代码供参考: - Frank Conry

6
当我使用SNS发布工具时,它会自动生成类似于以下的JSON格式:
{ 
    "default": "<enter your message here>", 
    "email": "<enter your message here>", 
    "sqs": "<enter your message here>", 
    "http": "<enter your message here>", 
    "https": "<enter your message here>", 
    "sms": "<enter your message here>", 
    "APNS": "{\"aps\":{\"alert\": \"<message>\",\"sound\":\"default\"} }", 
    "GCM": "{ \"data\": { \"message\": \"<message>\" } }", 
    "ADM": "{ \"data\": { \"message\": \"<message>\" } }" 
 }

这更接近苹果在其“通知负载”部分中所讨论的规范。他们指出消息应该是:
a JSON dictionary object (as defined by RFC 4627). 
This dictionary must contain another dictionary identified by the key aps.
The aps dictionary contains one or more properties

您是否尝试提供更接近该规范的消息?例如,像这样:

{
    'default':'default message', 
    {
        'aps':{
            'alert':'inner message',
            'sound':'mySound.caf'
         }
    }
 }

或者按照发布SNS发布工具的示例:

{
    'default':'default message',
    'APNS': {
        'aps':{
            'alert':'inner message',
            'sound':'mySound.caf'
         }\
     }
 }

也许还可以使用反斜杠转义。

答案是APNS对象需要编码为字符串,而不是大消息对象内部的子JSON字典。不过还是感谢您的撰写! - bryanjclark
2
啊,是的,这很有道理,因为在亚马逊的SNS示例中引号是被转义的。 - aychedee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接