在Python中格式化APNS样式的JSON消息以与Amazon SNS一起使用

bry*_*ark 18 python json amazon-web-services apple-push-notifications amazon-sns

我正在创建一个iOS应用程序,而对于我们的推送通知,我们正在使用亚马逊的简单通知服务(SNS).

SNS很精彩,但文档很少.我正在使用亚马逊的Python库boto,我已经找到了如何发送纯文本推送通知:

device_arn = 'MY ENDPOINT ARN GOES HERE'
plain_text_message = 'a plaintext message'
sns.publish(message=plain_text_message,target_arn=device_arn)
Run Code Online (Sandbox Code Playgroud)

但是,文档中不清楚的是如何创建Apple推送通知服务(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')
Run Code Online (Sandbox Code Playgroud)

但是,当我运行此代码时,我在通知上看到的只是"默认消息" - 这意味着Amazon SNS拒绝了我的消息格式,default而是显示了该消息.

如何正确格式化此JSON?

bry*_*ark 48

我想到了! 事实证明,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')
Run Code Online (Sandbox Code Playgroud)

以下是此代码中正在发生的事情的演练:

首先,为APNS创建python字典:

apns_dict = {'aps':{'alert':'inner message','sound':'mySound.caf'}}
Run Code Online (Sandbox Code Playgroud)

其次,取出该字典,并将其转换为JSON格式的字符串:

apns_string = json.dumps(apns_dict,ensure_ascii=False)
Run Code Online (Sandbox Code Playgroud)

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

message = {'default':'default message','APNS_SANDBOX':apns_string}
Run Code Online (Sandbox Code Playgroud)

接下来,我们进行编码在它自己的JSON格式的字符串:

messageJSON = json.dumps(message,ensure_ascii=False)
Run Code Online (Sandbox Code Playgroud)

然后可以使用boto发布生成的字符串:

sns.publish(message=messageJSON,target_arn=device_arn,message_structure='json')
Run Code Online (Sandbox Code Playgroud)


ayc*_*dee 5

当我使用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>\" } }" 
 }
Run Code Online (Sandbox Code Playgroud)

这看起来更接近苹果在" 通知有效载荷 "部分中谈到的规范.他们声明信息应该在哪里

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
Run Code Online (Sandbox Code Playgroud)

您是否尝试过提供更接近该规范的消息?比如这样的东西:

{
    'default':'default message', 
    {
        'aps':{
            'alert':'inner message',
            'sound':'mySound.caf'
         }
    }
 }
Run Code Online (Sandbox Code Playgroud)

或者遵循发布SNS发布工具中的示例:

{
    'default':'default message',
    'APNS': {
        'aps':{
            'alert':'inner message',
            'sound':'mySound.caf'
         }\
     }
 }
Run Code Online (Sandbox Code Playgroud)

也许还使用他们的反斜杠逃避.

  • 啊,是的,因为报价在亚马逊的SNS示例中被转义,这是有道理的. (2认同)