具有自定义 iOS 负载的亚马逊简单通知服务并不那么简单

Amazon Simple Notification Service with custom iOS payload not so simple

发送纯文本通知很简单,而且有据可查。但是我今天一直在为 iOS 发送自定义通知而烦恼,该通知具有警报和一些字段,例如 userId。

我从 this help page and implemented something similar to the last sample, then I found this answer 开始,它似乎使帮助页面上的最后一个示例无效,因为 "url" 属性 应该在 "aps" 对象之外。我尝试了很多组合,但每个组合都作为文本发送到应用程序(整个消息,带有 "default" 属性 和 "APNS" 对象)...

如果我将 MessageStructure 显式设置为 json,我会收到错误消息:"Invalid parameter: Message Structure - JSON message body failed to parse" 但我很确定我的 JSON 是好的,当发送到 SNS 时,消息中的字符串属性 看起来像这样:

{ "default":"You received a new message from X.", 
 "APNS_SANDBOX":"{ \"aps\": {\"alert\":\"You received a new message from X.\"}, 
                \"event\":\"Message\", 
                \"objectID\":\"7a39d9f4-2c3f-43d5-97e0-914c4a117cee\"
            }", 
 "APNS":"{ \"aps\": {\"alert\":\"You received a new message from X.\"}, 
                \"event\":\"Message\", 
                \"objectID\":\"7a39d9f4-2c3f-43d5-97e0-914c4a117cee\"
            }" 
}

有人有在 C# 中通过 SNS 发送带有自定义负载的通知的好例子吗?因为亚马逊肯定没有...谢谢!

奇怪的是,当我通过使用 类 和序列化对象而不是仅仅发送格式化的字符串来实现这种简洁的方法时,它起作用了。唯一的区别是间距...在干净版本中,除了 属性 值外没有空格:

{"default":"You received a new message from X.","APNS_SANDBOX":"{\"aps\":{\"alert\":\"You received a new message from X.\"},\"event\":\"Message\",\"objectID\":\"7a39d9f4-2c3f-43d5-97e0-914c4a117cee\"}","APNS":"{\"aps\":{\"alert\":\"You received a new message from X.\"},\"event\":\"Message\",\"objectID\":\"7a39d9f4-2c3f-43d5-97e0-914c4a117cee\"}"}

这些是我正在序列化的 类(目前仅适用于 APNS),使用您需要的任何属性而不是 Event 和 ObjectID:

[DataContract]
public class AmazonSNSMessage
{
    [DataMember(Name = "default")]
    public string Default { get; set; }

    [DataMember(Name = "APNS_SANDBOX")]
    public string APNSSandbox { get; set; }

    [DataMember(Name = "APNS")]
    public string APNSLive { get; set; }

    public AmazonSNSMessage(string notificationText, NotificationEvent notificationEvent, string objectID)
    {
        Default = notificationText;
        var apnsSerialized = JsonConvert.SerializeObject(new APNS
        {
            APS = new APS { Alert = notificationText },
            Event = Enum.GetName(typeof(NotificationEvent), notificationEvent),
            ObjectID = objectID
        });
        APNSLive = APNSSandbox = apnsSerialized;
    }

    public string SerializeToJSON()
    {
        return JsonConvert.SerializeObject(this);
    }
}

[DataContract]
public class APNS 
{
    [DataMember(Name = "aps")]
    public APS APS { get; set; }

    [DataMember(Name = "event")]
    public string Event { get; set; }

    [DataMember(Name = "objectID")]
    public string ObjectID { get; set; }
}

[DataContract]
public class APS
{
    [DataMember(Name = "alert")]
    public string Alert { get; set; }
}

所以我通过以下方式获取 Amazon SNS 消息:

new AmazonSNSMessage(...).SerializeToJSON();

刚刚为我解决此问题的关键是意识到特定于 SNS 的外部 JSON(例如 "default" 和 "APNS" 属性)不得转义,只能转义内部有效载荷。例如,此 Message 值成功(仅发布开始):

{"APNS":"{\"aps\" ... 

请注意,第一个 属性 "APNS" 没有转义,但随后 它的值 (将攻击设备的实际负载)被转义。完成以下工作:

JObject payload = ... // your apns, etc payload JObject

var snsMsgJson = new JObject(
    new JProperty("default", "message 1 2 3"), // "default" is optional if APNS provided
    new JProperty("APNS", payload.ToString(Formatting.None))
);

string str = snsMsgJson.ToString(Formatting.None);

我看上面的例子就明白了,谢谢!但是,我知道上面 'clean classes' 所谓的解决方案实际上不能也不应该是一个要求。所以当他说:"The only difference was the spacing... in the clean version there are no spaces except in the property values" 那是不正确的。真正的区别正如我所说,外部(特定于 SNS)JSON 应 被转义,但内部 必须 .

肥皂盒:那个文档怎么样? API 中的许多事情浪费了大量时间,同样重要的是:一个人的幸福感。尽管如此,我还是很感谢这项服务。