I'm trying to create a subscription using CloudKit to fires every time a record is created. I have successfully created the subscription, I can see it in dashboard, but I've noticed that the print I have in didReceiveRemoteNotification was never printed!
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("oioioioioi")
let viewController: CurrentEventController = self.window?.rootViewController as! CurrentEventController
if let userInfo = userInfo as? [String: NSObject] {
let notification: CKNotification = CKNotification(fromRemoteNotificationDictionary: userInfo)
if (notification.notificationType == CKNotificationType.Query) {
let queryNotification = notification as! CKQueryNotification
let recordID = queryNotification.recordID
viewController.fetchRecord(recordID!)
}
}
}
Thanks for any help!
Related
I am using swift3. I want to show FCM message to tableview in a UIViewController when My app receive FCM message data.I have got my fcm data using bellow code in appDelegate..But I don't know how to get data in UIViewController.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (_ options: UNNotificationPresentationOptions) -> Void) {
let message : UNNotificationPresentationOptions = .alert
//GlobalVariables.notification_message = getAlert(notification: .alert)
if UIApplication.shared.applicationState == .active { // In iOS 10 if app is in foreground do nothing.
print("active****")
print("\(notification.request.content.userInfo)")
completionHandler([message, .sound])
} else {
print("Not active****")
completionHandler([message, .badge, .sound])
}
}
Please help me
Thanks advance
Set a variable on your AppDelegate, then use it from either:
AppDelegate's didFinishLaunchingWithOptions on window?.rootViewController
Your view controller by calling (UIApplication.shared.delegate as? AppDelegate)?.yourVariable
I recommend setting variable in AppDelegate to nil after using it, to prevent using same notification data twice.
In app delegate change your code like this
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.sandbox)
// FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.prod)
}
func applicationWillTerminate(_ application: UIApplication) {
UserDefaults.standard.removeObject(forKey: "check")
UserDefaults.standard.removeObject(forKey: "userid")
UserDefaults.standard.removeObject(forKey: "patient_no")
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
let state: UIApplicationState = UIApplication.shared.applicationState
if state == .active{
UIApplication.shared.applicationIconBadgeNumber = 0
if let notification = userInfo["aps"] as? [AnyHashable: Any],
let alert = notification["alert"] as? String {
print(alert)
message = alert
let localNotification = UILocalNotification()
localNotification.alertBody = alert
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.shared.scheduleLocalNotification(localNotification)
print("Active----")
}
}else if state == .inactive{
if let notification = userInfo["aps"] as? [AnyHashable: Any],let alert = notification["alert"] as? String {
print(alert)
message = alert
let localNotification = UILocalNotification()
localNotification.alertBody = alert
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.shared.scheduleLocalNotification(localNotification)
print("Inactive----")
}
}else if state == .background{
if let notification = userInfo["aps"] as? [AnyHashable: Any],let alert = notification["alert"] as? String,let sound = notification["sound"] as? String{
print(alert)
message = alert
var localNotification = UILocalNotification()
localNotification.alertBody = alert
localNotification.soundName = sound
UIApplication.shared.applicationIconBadgeNumber = number!+1
print(number!+1)
UIApplication.shared.scheduleLocalNotification(localNotification)
print("Background----")
}
}
}
then add this where you want the message back
let delegate = UIApplication.shared.delegate as! AppDelegate
let message = delegate.message
This is a sample only you want to add some condition
Ok so my push notification work like a charm when the app is running in the foreground. But when ever I enter into the background, the app never receives the push notification. Its like the notification falls on deaf ears.
So this is what happening. When the app is first started, I can received notification. When I close and reopen the app I can receive notification. But when the app is closed in the background I cannot receive notification. I print off when the app goes into the background and when the app becomes active so I know that its not closing I think. Because its printing that its going into the background, so it should be running.
So this is what I have for the app deligate class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//OTHER THINGS
//Open the Push note page
if launchOptions != nil
{
print(launchOptions)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier(myPage)
self.window?.rootViewController = vc
}
//handel push note if app is closed
//Sends it to the regular handler for push notifcaiton
//didrecivepushnotificaiton
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary
{
print("Got A Push Note when I was closed")
self.application(application, didReceiveRemoteNotification: remoteNotification as [NSObject : AnyObject])
}
}
func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: NSData ) {
print("DEVICE TOKEN = \(deviceToken)")
//convert the device token into a string
let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
var token = ""
for i in 0..<deviceToken.length {
token += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
print("token: " + token)
//store the user device token for apns push notification
loginInformation.setObject(token, forKey: "token")
self.loginInformation.synchronize()
}
// [START ack_message_reception]
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Recived Push Notificaion")
var myMess :String = ""
var url : String = ""
var myTitle : String = ""
if var alertDict = userInfo["aps"] as? Dictionary<String, String> {
print("Alert Dict")
print(alertDict)
url = alertDict["url"]!
myMess = alertDict["alert"]!
myTitle = alertDict["mytitle"]!
//store the url for the push control view
loginInformation.setObject(url, forKey: "URL")
loginInformation.setObject(myMess, forKey: "Message")
loginInformation.setObject(myTitle, forKey: "Title")
self.loginInformation.synchronize()
}else{print("No go")}
application.applicationIconBadgeNumber = 0
//post notification.
NSNotificationCenter.defaultCenter().postNotificationName("PushReceived", object: nil, userInfo: userInfo)
if myTitle == ""
{
myTitle = “New Title“
}
if myMess == ""
{
myMess = “All Hail Gus“
}
let alert = UIAlertController(title: myTitle, message: myMess, preferredStyle: UIAlertControllerStyle.Alert)
//Close Button
alert.addAction(UIAlertAction(title: "次回", style: UIAlertActionStyle.Default, handler: nil))
self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}
func registrationHandler(registrationToken: String!, error: NSError!) {
}
// [START receive_apns_token_error]
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: NSError ) {
print(error)
}
I think I have all the right setting on this too. But I am not too sure now. The push notifications did work but I made a lot of changes and haven't tested them in a while.
And this is an example of the payload
{"aps":{"alert":"Gus Message.","badge":"1", "url":"https://www.gus.com","mytitle":"Gus Title"}}
To fully implement APNS servie, u have to handle three cases:
inactive
foreground
background
the inactive mode should be handled in didFinishLaunchingWithOptions method
//receive apns when app in inactive mode, remaining message hint display task could be sum up by the code in applicationwillenterforeground
if let options = launchOptions {
if options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil {
let userInfo: NSDictionary = options[UIApplicationLaunchOptionsRemoteNotificationKey] as! NSDictionary
let apsInfo: NSDictionary = userInfo["aps"] as! NSDictionary
//parse notification body message ...
NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_REMOTE_NOTIF, object: userInfo)
APService.handleRemoteNotification(userInfo as! [NSObject : AnyObject])
//Update badge number
let badgeIndex = apsInfo["badge"] as! Int
UIApplication.sharedApplication().applicationIconBadgeNumber = badgeIndex
}
}
} else if options[UIApplicationLaunchOptionsURLKey] != nil {
if let url = launchOptions?[UIApplicationLaunchOptionsURLKey] as? NSURL {
print(url)
}
}
}
the remaining two cases should be handle in didReceiveRemoteNotification method
//receive apns when app in background mode
let apsInfo: NSDictionary = userInfo["aps"] as! NSDictionary
if UIApplication.sharedApplication().applicationState != UIApplicationState.Active{
//TODO: temporary method, need further update
//judge notification type
if let _ = userInfo["inviterName"] as? String {
//notification for group invite
}else{
//Update badge number
if let badgeInt = apsInfo["badge"] as? Int {
UIApplication.sharedApplication().applicationIconBadgeNumber = badgeInt > 0 ? badgeInt: 1
}else{
UIApplication.sharedApplication().applicationIconBadgeNumber = 1
}
//turn on trigger to enable message hint btn on recorder vc when it appear
NSUserDefaults.standardUserDefaults().setBool(true, forKey: REMOTE_NOTIF_REMAINING)
}
}
//receive apns when app in forground mode
else{
//TODO: temporary method, need further update
//judge notification type
if let _ = userInfo["inviterName"] as? String {
//notification for group invite
NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_GROUP_NOTIF, object:nil)
}else{
//notificate recorder vc to display message hint directly
NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_REMOTE_NOTIF, object: userInfo)
}
}
APService.handleRemoteNotification(userInfo)
completionHandler(UIBackgroundFetchResult.NewData)
I am working with Push notification and local notification also but in foreground notification working fine but when terminate app in this condition i can not able to redirect specific view when tap on notifications.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Check if launched from notification
// 1
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
// 2
let aps = notification["aps"] as! [String: AnyObject]
//Redirect to notification view
handlePushMessage(aps)
}else if let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? [String: AnyObject] {
// 2
self.postData = notification["aps"] as! [String: AnyObject]
//Redirect to notification view
didTapNotification()
}else{
//Session
//Redirect to Main view
checkUserSession()
}
return true
}
I am facing this facing this problem from both APNS notification and local notification when app is Inactive or terminate.Please help me fro find the solution.
How about you try in didReceiveRemoteNotification function?
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if(application.applicationState == UIApplicationStateBackground){
}else if(application.applicationState == UIApplicationStateInactive){
}
}
try this code, you can modify it according to you requirement. if you have any problem understanding this logic let me know. didReceiveRemoteNotification with completionHandler works both in background and in foreground. Don't forget to do appropriate changes in plist to support background fetch and background notification.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
notificationDataDict = notification;
}
return true
}
func handleRemoteNotificationWithUserInfo(application:UIApplication, userInfo:NSDictionary){
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print(userInfo)
if application.applicationState != .Inactive{
notificationDataDict = userInfo;
if let navigationController = self.window?.rootViewController as? UINavigationController{
if application.applicationState == .Active{
if application.backgroundRefreshStatus == .Available{
completionHandler(.NewData)
self.handleRemoteNotificationWithUserInfo(application, userInfo: userInfo)
}
else
{
completionHandler(.NoData)
}
}
else{
completionHandler(.NewData)
self.handleRemoteNotificationWithUserInfo(application, userInfo: userInfo)
}
}
}
}
Finally i got the solution for Manage APNS Push notification and Local notification, its working fine now.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
//Register here For Notification
if #available(iOS 9, *) {
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
}else{
UIApplication.sharedApplication().registerUserNotificationSettings(
UIUserNotificationSettings(forTypes: .Alert, categories: nil))
application.registerForRemoteNotifications()
}
dispatch_async(dispatch_get_main_queue()) {
// Check if launched from notification
// 1
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
// 2
let aps = notification["aps"] as! [String: AnyObject]
handlePushMessage(aps)
}else if let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
// 2
self.postData = notification.userInfo as! [String: AnyObject]
didTapNotification()
}else{
//Session
checkUserSession()
}
}
}
I tried to receive my custom notification from my web through parse website.
Code didReceiveRemoteNotification :
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)}
Here is the JSON i received from parse website :
[aps: {
alert = "test adirax";
sound = default; }]
It works well for me and the notification shows up. However when i tried to push data from my website, the notification can't shows/ pop up.
Here is my JSON looks like :
{"aps": {"alerts" : "test",
"links": "",
"sounds": "default"}}
I tried to print(userInfo) and the result is i get all the data like above, but there is no notif.
I guess I'm missing some code to convert the data ?
INFORMATION
For the specific information, i tried receive notification from parse.com through subscribe "channels". so it's not a local notification or else.
ADD Code Added (according to my JSON type)
if let launchOptions = launchOptions {
let userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject: AnyObject]
let aps = userInfo!["aps"] as? [NSObject: AnyObject]
let alert1 = aps!["alerts"] as? String
let link1 = aps!["links"] as? String
}
And this :
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let alert1 = aps!["alerts"] as? String
let link1 = aps!["links"] as? String
print(userInfo)
print("success")
}
When i debugged one by one, its success i collect all the data, however i still missing the notification showed up ?
SOLVED PART 1
So far i managed to get the data and push the notification out, but it's only when i open the application. Code :
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
let notifiAlert = UIAlertView()
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let alert1 = aps!["alerts"] as? String
let link1 = aps!["links"] as? String
notifiAlert.title = alert1!
notifiAlert.message = link1
notifiAlert.addButtonWithTitle("OK")
notifiAlert.show()
print(userInfo)
print("success")
}
I use a local notification trick, but how to pop up the notification when i'm not using the app ?
You have to add custom informations like this:
{"aps": {"alerts" : "test",
"sound": "default"},
"name": "Steven",
"age": "32"
}
And parse it like this:
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let msg = aps!["alert"] as? String
let name = userInfo["name"] as? String
print(name)
EDIT:
You have to check push notification on two functions of UIApplicationDelegate
First.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// check for push message
if let launchOptions = launchOptions {
let userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject: AnyObject]
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let msg = aps!["alert"] as? String
let name = userInfo["name"] as? String
print(name)
}
}
Second.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let msg = aps!["alert"] as? String
let name = userInfo["name"] as? String
print(name)
}
You should add your custom data to the top-level of your payload, not to the aps object.
Like this, for instance:
{
"aps": {
"alerts" : "test",
"sounds": "default"
},
"links": "",
}
This is my ReceiveRemoteNotification code.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
let notifiAlert = UIAlertView()
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let alert1 = aps!["alerts"] as? String
let link1 = aps!["links"] as? String
notifiAlert.title = alert1!
notifiAlert.message = link1
notifiAlert.addButtonWithTitle("OK")
notifiAlert.show()
print(userInfo)
print("success")
}
i tried to receive JSON data from my web, my JSON looks like :
{"aps":{"alerts":"3","links":"","sounds":"default"}}
I did receive the Json data and turn the data to the view. with this code :
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let alert1 = aps!["alerts"] as? String
let link1 = aps!["links"] as? String
notifiAlert.title = alert1!
notifiAlert.message = link1
notifiAlert.addButtonWithTitle("OK")
notifiAlert.show()
print(userInfo)
print("success")
}
However i only receive when i was using the application, but if i'm not using, i can't receive the notification. but my phone was vibrate or make sound, but no message.
Am i missing something right here ? thanks !
Added Here is my full code http://pastebin.com/mkFiq6Cs
EDIT
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let alert1 = aps!["alerts"] as? String
let link1 = aps!["links"] as? String
notifiAlert.title = alert1!
notifiAlert.message = link1
notifiAlert.addButtonWithTitle("OK")
notifiAlert.show()
print(userInfo)
print("success")
}
So i have to add this code :
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
if let userInfo = notification.userInfo {
let aps = userInfo["aps"] as? [NSObject: AnyObject]
let alert2 = aps!["alerts"] as? String
let link2 = aps!["links"] as? String
print("didReceiveLocalNotification: \(aps)")
print("didReceiveLocalNotification: \(alert2)")
print("didReceiveLocalNotification: \(link2)")
}
}
And this at didFinishLaunchingOption :
if let options = launchOptions {
if let notification = options[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
if let userInfo = notification.userInfo {
let customField1 = userInfo["CustomField1"] as! String
// do something neat here
}
}
}
SOLVED
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
let notifiAlert = UIAlertView()
if let aps = userInfo["aps"] as? [NSObject: AnyObject],
let alert1 = aps["alert"] as? String,
let content1 = aps["content-available"] as? String,
let link1 = userInfo["links"] as? String {
notifiAlert.title = alert1
notifiAlert.message = link1
notifiAlert.addButtonWithTitle("OK")
notifiAlert.show()
}
print(userInfo)
print("success")
completionHandler(UIBackgroundFetchResult.NewData)
}
This works perfectly. ! Thanks to #tskulbru
This is because application(_:didReceiveRemoteNotification:) is only called when the application is active. It cant handle app-inactive/background remote notifications.
If the app is not running when a remote notification arrives, the method launches the app and provides the appropriate information in the launch options dictionary. The app does not call this method to handle that remote notification. Instead, your implementation of the application:willFinishLaunchingWithOptions: or application:didFinishLaunchingWithOptions: method needs to get the remote notification payload data and respond appropriately.
Source: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html?hl=ar#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveRemoteNotification:
As said above, application:didReceiveRemoteNotification needs to have additional implementation if it should be able to handle background notifications.
If you instead want just one method to handle all the goodies for you, and don't have a bunch of different methods to implement basically the same thing, Apple has provided a method called application:didReceiveRemoteNotification:fetchCompletionHandler: to handle all this for you.
You need to implement the application:didReceiveRemoteNotification:fetchCompletionHandler: method instead of this one to handle background notifications. This handles background tasks, and you can then call the completionHandler with the appropiate enum when you are finished (.NoData / .NewData / .Failed).
If you want to have a local notification presented when you receive a remote notification while the application is active you will need to create that in the aforementioned method. And if you want to display an alertview if the application is active, you also need to handle the two scenarios in that method. My recommendation is to switch to application:didReceiveRemoteNotification:fetchCompletionHandler: instead and implement everything there.
So in your case, I would do something like this:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
} else {
let notifiAlert = UIAlertView()
if let aps = userInfo["aps"] as? [NSObject: AnyObject],
let alert1 = aps["alerts"] as? String,
let link1 = aps["links"] as? String {
notifiAlert.title = alert1
notifiAlert.message = link1
notifiAlert.addButtonWithTitle("OK")
notifiAlert.show()
}
print(userInfo)
print("success")
}
completionHandler(UIBackgroundFetchResult.NewData)
}
I've not tested the code but it should be something like that without too many changes. I havent used Parse so I don't know exactly what PFPush.handlePush(userInfo) does, you need to check the documentation for that.
Looks like your apns payload is wrong too. See https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH107-SW1
In your case:
{"aps":{"alert":"alert content","sound":"default", "content-available": 1}, "links":""}
You had plural form instead of single form. Look at the url I gave for the allowed keys. The links key doesn't exist in aps dictionary, which mean its a custom key and needs to be placed outside the dictionary.
Note that this is the standard push notification way and might not be correct when using Parse.