leonard
leonard

Reputation: 2387

AWS SNS send remote notification directly from iOS always error

I am using AWS SNS (v2.0) for my iOS app (iOS 8) to send out remote notifications directly to another user. There is no proxy in the middle for the notification. But constantly, I have this problem where as soon as I want to send out a JSON message as below, I will get error. When I switch back to pure text, the notification is delivered and received with no problem.

    let sns = AWSSNS.defaultSNS()
    let request = AWSSNSPublishInput()
    request.messageStructure = "json"

    var notificationKeys = MONotificationKeys()
    var aps: NSMutableDictionary = NSMutableDictionary()
    aps.addEntriesFromDictionary(["alert": "Hello World"])
    aps.addEntriesFromDictionary(["sound": "sound.wav"])
    aps.addEntriesFromDictionary(["badge": 1])
    var raw1: NSDictionary = NSDictionary(dictionary: ["aps":aps])
    var raw2: NSDictionary = NSDictionary(dictionary: ["APNS_SANDBOX":raw1])
    var dataWithJSON = NSJSONSerialization.dataWithJSONObject(raw2, options: NSJSONWritingOptions.allZeros, error: nil)
    request.message = NSString(data: dataWithJSON!, encoding: NSUTF8StringEncoding)
    request.targetArn = targetEndpointARN

    sns.publish(request).continueWithExecutor(BFExecutor.mainThreadExecutor(), withSuccessBlock: { (task: BFTask!) -> AnyObject! in
        println(task.result)
        return nil
    }).continueWithExecutor(BFExecutor.mainThreadExecutor(), withBlock: { (task: BFTask!) -> AnyObject! in
        if (task.error != nil) {
            println("Error: \(task.error.userInfo)")
        }
        return nil
    })

And the error is:

Error: Optional([Code: InvalidParameter, 
Message: Invalid parameter: JSON must contain an entry for 'default' or 'APNS_SANDBOX'., __text: (
"\n    ",
"\n    ",
"\n    ",
"\n  "), 
Type: Sender])

The print out of what the message is:

{ "APNS_SANDBOX" : 
 {
  "aps" : {
    "sound" : "mo.wav",
    "badge" : 1,
    "alert" : "Hello World"
  }
 }
}

You guys know what causes this error? THANKS!

Upvotes: 4

Views: 3835

Answers (5)

Sheik Mubarak
Sheik Mubarak

Reputation: 1

APNS_SANDBOX:

 JSON.stringify({
            aps: {
                alert: "hello vietnam"
            }
        })

try like this to get hello vietnam instead of ENTER YOUR MESSAGE.

Upvotes: -3

Can-Do spirit
Can-Do spirit

Reputation: 23

Please put your code here to make the answer clearer. i sent:

{
    "default" : "ENTER YOUR MESSAGE",
    "APNS_SANDBOX" : {
        "aps" : {
            "badge" : 1,
            "alert" : "hello vietnam"
        }
    }
}

and then i always receive the same message content : "ENTER YOUR MESSAGE" rather than "hello vietnam"

Thanks much!

Upvotes: 0

hbk
hbk

Reputation: 11184

@leonard are right

same in Objective-C

NSDictionary *sampleMessage = @{
                                @"default": @"This is the default message which must be present when publishing a message to a topic. The default message will only be used if a message is not present one of the notification platforms",
                                @"APNS_SANDBOX": @"{\"aps\":{\"alert\": \"YOUR_MESSAGE\",\"sound\":\"default\", \"badge\":\"1\"} }"
                                };
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:sampleMessage options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

AWSSNS *sns = [AWSSNS defaultSNS];
AWSSNSPublishInput *message = [[AWSSNSPublishInput alloc] init];
message.subject = @"test";
message.targetArn = [[NSUserDefaults standardUserDefaults] objectForKey:@"endpointArn"];
message.message = jsonString;
message.messageStructure = @"json";

[[sns publish:message] continueWithBlock:^id _Nullable(AWSTask<AWSSNSPublishResponse *> * _Nonnull task) {

    if (task.error) {
        NSLog(@"The request failed. Error: [%@]", task.error);
    }
    if (task.exception) {
        NSLog(@"The request failed. Exception: [%@]", task.exception);
    }
    if (task.result) {
        //Do something with the result.
    }
    return nil;
}];

Upvotes: 0

Ryan Romanchuk
Ryan Romanchuk

Reputation: 10879

Man this took forever to figure out. AWS's SNS documentation is horrible. Here is how you you can publish to a topic using swift. Each platform needs to be an encoded string, if you mess this up SNS will only deliver your default message.

func publishPush() {
    let sns = AWSSNS.defaultSNS()
    let request = AWSSNSPublishInput()
    request.messageStructure = "json"

    var dict = ["default": "The default message", "APNS_SANDBOX": "{\"aps\":{\"alert\": \"YOUR_MESSAGE\",\"sound\":\"default\", \"badge\":\"1\"} }"]

    let jsonData = NSJSONSerialization.dataWithJSONObject(dict, options: nil, error: nil)
    request.message = NSString(data: jsonData!, encoding: NSUTF8StringEncoding) as! String
    request.targetArn = "blahblahblah:MyTopic"
    sns.publish(request).continueWithBlock { (task) -> AnyObject! in
        println("error \(task.error), result:; \(task.result)")
        return nil
    }

}

Upvotes: 3

leonard
leonard

Reputation: 2387

I've got this answer from AWS Forum:

SNS Publish Message is a a JSON dictionary where both key and value must be strings. The value of key "APNS_SANDBOX" is a dictionary not a string. Please escape the JSON value to a string and pass it.

Then it works :D

Upvotes: 3

Related Questions