6

I'm trying to follow the Parse Guide to handle the notifications i send in Json format, but i'm having a problem, here is my code:

  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
        // Override point for customization after application launch.
        Parse.setApplicationId("MyAppId", clientKey: "MyAppClientKey")

        var notificationType: UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound

        var settings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationType, categories: nil)
        UIApplication.sharedApplication().registerUserNotificationSettings(settings)
        UIApplication.sharedApplication().registerForRemoteNotifications()

if let launchOptions = launchOptions {
    var notificationPayload: NSDictionary = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as NSDictionary!
    println(launchOptions)

    var url = notificationPayload["url"] as String

    var feed: FeedTableViewController = FeedTableViewController()
    feed.messages.insert(url, atIndex: 0)
    feed.sections.insert("section", atIndex: 0)
    }


        return true
    }

the app doesn't crash now, but the changes i made doesn't take place. Json code:

{
    "aps": {
         "badge": 10,
         "alert": "Test",
         "sound": "cat.caf"
    },
    "url": "http://www.google.com"
}
Abdou023
  • 1,654
  • 2
  • 24
  • 45

3 Answers3

9

I'm guessing your problem is here:

launchOptions(UIApplicationLaunchOptionsRemoteNotificationKey) as NSDictionary 

I'm not sure what you're expecting, but as far as I know, there's no method like that on a dictionary. You might be looking for subscript syntax. Something like this:

launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as NSDictionary 

To get a dictionary nested within the launchOptions dictionary under the key: UIApplicationLaunchOptionsRemoteNotificationKey.

That being said, launchOptions could be nil, you should add that check in your code and also, try logging launchOptions and post the results here.

You can check if launchOptions are nil like this:

if let launchOpts = launchOptions {
    var notificationPayload: NSDictionary = launchOpts.objectForKey(UIApplicationLaunchOptionsRemoteNotificationKey) as NSDictionary
}
Logan
  • 52,262
  • 20
  • 99
  • 128
  • Please, check my updated post, and what to do if launchoptions == nil ? – Abdou023 Oct 07 '14 at 20:27
  • Updated for how to check for nil, I'm not sure what you should do if they are nil. I assume if they're nil, the application wasn't opened via a notification and you should just continue. – Logan Oct 07 '14 at 20:34
  • This worked, but now i'm not able to make the notification affect my app. please check my edit. – Abdou023 Oct 07 '14 at 21:09
  • I'm not sure what you mean by "affect my app". This is where you would respond to your notification in opening the app. For example, if the user tapped on your notification, you could use this to interpret what notification was tapped and respond within your app accordingly. What would you like to have happen that is not happening? – Logan Oct 07 '14 at 21:18
  • Take a look at my code above, i'm trying to send a String to be added to my table in a json format, my phone recieves and displays the message, but my table never get updated or changed. – Abdou023 Oct 07 '14 at 21:20
  • Unless the user taps on your notification, this code will not run. This only runs on app launch, and you only get the notification data if it launched as a result of the notification press. I'm guessing you want: `- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler` – Logan Oct 07 '14 at 21:22
  • I do open the app by clicking on the notification, no effect. – Abdou023 Oct 07 '14 at 21:26
  • Then your issue is probably here: `var feed: FeedTableViewController = FeedTableViewController() feed.messages.insert(url, atIndex: 0) feed.sections.insert("section", atIndex: 0)` You instantiate `feed`, but you don't do anything with it. – Logan Oct 07 '14 at 21:28
  • Im just instantiating it so i can add the new element from the notification into the array inside that viewController. – Abdou023 Oct 07 '14 at 21:31
  • You need to either launch that instance, or get a reference to the actual view controller you are launching (both are well documented if you google around). Right now, you're creating a new instance, assigning it some values, and then at the end of the function, your app launches a different instance, and the instance that you assigned all the values to is removed from memory. – Logan Oct 07 '14 at 22:14
  • Please check this thread. http://stackoverflow.com/questions/26286148/xcode-push-notification-json – Abdou023 Oct 09 '14 at 20:03
3

NSDictionary's objectForKey returns an optional:

func objectForKey(_ aKey: AnyObject) -> AnyObject?

so if you force unwrap it using the ! you take your risk if the Optional contains nil. You should force unwrap only when you're 100% sure that the Optional contains a value but in this case the UIApplicationLaunchOptionsRemoteNotificationKey is set only when the application is launched when the user taps on the remote notification message in the notification center.

You must check for the Optional and downcast to NSDictionary using as?:


if let myDict = launchOptions[UIApplicationLaunchOptionsRemoteNotifcationKey] as? NSDictionary {
// there is a notification
} else {
// no notification
}

(the "as? NSDictionary" is not strictly required, as you can downcast later; if you don't downcast Swift will warn you that the myDict object will be inferred as AnyObject.

viggio24
  • 12,316
  • 5
  • 41
  • 34
2
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {

}
MobileMon
  • 8,341
  • 5
  • 56
  • 75