20

I am trying to handle the launch option and open a specific view controller upon tapping a remote notification that I receive in swift 3. I have seen similar question, for instance here, but nothing for the new swift 3 implementation. I saw a similar question (and ) In AppDelegate.swift I have the following in didFinishLaunchingWithOptions:

    var localNotif = (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as! String)
if localNotif {
    var itemName = (localNotif.userInfo!["aps"] as! String)
    print("Custom: \(itemName)")
}
else {
    print("//////////////////////////")
}

but Xcode is giving me this error:

Type '[NSObject: AnyObject]?' has no subscript members

I also tried this:

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

    }

and I get this error:

error: ambiguous reference to member 'subscript'

I got similar errors wherever I had previously used similar code to get a value from a dictionary by the key and I had to replace the codes and basically safely unwrap the dictionary first. But that doesn't seem to work here. Any help would be appreciated. Thanks.

mfaani
  • 33,269
  • 19
  • 164
  • 293
TheBen
  • 3,410
  • 3
  • 26
  • 51

5 Answers5

34

Apple made plenty of changes in Swift 3 and this one of them.

Edit: This works for Swift 4 as well.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    //Launched from push notification
    let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any]
    if remoteNotif != nil {
        let aps = remoteNotif!["aps"] as? [String:AnyObject]
        NSLog("\n Custom: \(String(describing: aps))")
    }
    else {
        NSLog("//////////////////////////Normal launch")
    }
}

Swift 5:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    //Launched from push notification
    guard let options = launchOptions,
        let remoteNotif = options[UIApplication.LaunchOptionsKey.remoteNotification] as? [String: Any]
        else {
            return
    }
    let aps = remoteNotif["aps"] as? [String: Any]
    NSLog("\n Custom: \(String(describing: aps))")
    
    handleRemoteNotification(remoteNotif)
}

And for more on LaunchOptionsKey read Apple's documentation.

kwl
  • 495
  • 6
  • 13
Adeel Miraj
  • 2,472
  • 3
  • 22
  • 32
  • I still get the error , ambiguous reference to member subscript! – TheBen Oct 24 '16 at 01:21
  • my bad, there was a mistake. try now – Adeel Miraj Oct 24 '16 at 01:23
  • Hmm, thanks but you sure you updated your response? seems to be the same – TheBen Oct 24 '16 at 01:26
  • 1
    Yes I have made a couple of changes. They are very minor that's why they aren't evident. – Adeel Miraj Oct 24 '16 at 01:28
  • So as I mentioned in the answer above it turned out the whole signature of didfinishwithoptions method has changed. Thanks for your comments again. – TheBen Oct 24 '16 at 03:40
  • Tried the Swift 5 solution but I am not getting value for the "remoteNotif". Any reason why this is happening. Except when app is killed in all other scenarios I am getting push notifications. – subin272 Jun 03 '20 at 17:53
  • @subin272 this code is for the case when app is killed and is launched through a notification. Can you share any further details to investigate the issue? – Adeel Miraj Jun 03 '20 at 20:47
  • @Adeel yes I am trying the same scenario you mentioned ie the app is killed. Then trying to launch it from push notification. I am checking it with an if else condition. – subin272 Jun 04 '20 at 03:33
  • @Adeel. if let options = launchOptions, let remoteNotif = options[UIApplication.LaunchOptionsKey.remoteNotification] as? [String: Any] { UserDefaults.standard.set("From remote", forKey: "NotificationPayload") } else { UserDefaults.standard.set("xyz", forKey: "NotificationPayload") } – subin272 Jun 04 '20 at 03:35
  • Is there any other way to verify the contents of "launchOptions" or test remote notifications when the app is killed? – subin272 Jun 04 '20 at 03:36
  • @subin272 its a strange behaviour. Can't really say why it might be happening. – Adeel Miraj Jun 04 '20 at 09:43
  • @Adeel Found a solution for this..seems its an iOS 13 issue. Link to the solution - https://stackoverflow.com/questions/60007715/launchoptions-always-nil-when-launching-from-a-push-notification – subin272 Jun 05 '20 at 07:26
16

So it turned out the whole method signature has changed and when I implemented the new signature things worked just fine. Below is the code.

new didFinishLaunchingWithOptions method:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {



//and then 
 if launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] != nil {


// Do what you want to happen when a remote notification is tapped.


}

}

Hope this helps.

TheBen
  • 3,410
  • 3
  • 26
  • 51
7

Swift 4

// Check if launched from the remote notification and application is close
 if let remoteNotification = launchOptions?[.remoteNotification] as?  [AnyHashable : Any] {
            // Do what you want to happen when a remote notification is tapped.
            let aps = remoteNotification["aps" as String] as? [String:AnyObject]
            let apsString =  String(describing: aps)
            debugPrint("\n last incoming aps: \(apsString)")
    }
Community
  • 1
  • 1
Amr Angry
  • 3,711
  • 1
  • 45
  • 37
0

swift 3:

        if let notification = launchOptions?[.localNotification] as? NSDictionary{

            #if DEBUG
                print("iOS9 didFinishLaunchingWithOptions notification\n \(notification)")
            #endif
ingconti
  • 10,876
  • 3
  • 61
  • 48
0
if let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any] {
       if let notification = remoteNotif["aps"] as? [AnyHashable : Any] {
               //handle PN
       }
}
Svitlana
  • 2,938
  • 1
  • 29
  • 38