0

I am trying to access a particular value from a variable that is of type [AnyHashable: Any] however, I am getting an error while accessing any value. I have browsed the internet regarding this issue, but I did not get any specific solution for it. So is there any other way to access them? Please help and thanks in advance.

Function where I am getting an error

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        //Print full message
        print(userInfo)

        guard let aps = userInfo[AnyHashable("gcm.notification.data")],
            let data = aps["filters"] as! String else { // Getting the error here
                return
        }
        print(aps)
        completionHandler(UIBackgroundFetchResult.newData)
    }

Fetched data on printing the userInfo

[AnyHashable("gcm.notification.data"): {"filters":"fjjnbbx zjbxzj","history":"dsfdxf","message":"value1","source":"message source"}]
Saurabh
  • 745
  • 1
  • 9
  • 33
  • Please [search on the error](https://stackoverflow.com/search?q=Type+%27Any%27+has+no+subscript+members). This has been covered many, many times. – rmaddy Jul 23 '18 at 06:21
  • @rmaddy I have looked for this error on stack overflow but they are not associated with type [AnyHashable: Any] – Saurabh Jul 23 '18 at 06:31
  • Please post code, data, logs, error message, etc as text (not images) so they are searchable – Ashley Mills Aug 30 '18 at 09:18
  • 1
    add a guard like this: guard let info = userInfo as? [String: Any] else {return} then You can check it like, guard let aps = info["gcm.notification.data"] as? [String: Any], let data = aps["filters"] as? String else {return} I guesss this would do the work. – Shivam Pokhriyal Jan 08 '19 at 04:04
  • @ShivamPokhriyal I already posted answer to my question that resolved the problem and thanks for your help :) – Saurabh Jan 08 '19 at 05:09
  • Ok! Didn't read your answer earlier. Though you should make use of guard rather than if statement. – Shivam Pokhriyal Jan 08 '19 at 07:40
  • @ShivamPokhriyal Yeah surely. Feel free to make any changes to the code that will improve the user performance. – Saurabh Jan 09 '19 at 06:29

2 Answers2

2

I resolved the issue as the information I was receiving was of type NSString (JSON in String) not NSDictionary / [String : Any]. I have provided the working code that solved my problem below -

if let notificationData = userInfo["gcm.notification.data"] as? NSString {
                var dictionary : NSDictionary?
                if let data = notificationData.data(using: String.Encoding.utf8.rawValue) {
                    do {
                        dictionary = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary
                        print("DICTIONARY : \(dictionary)")
                        if let dict = dictionary {
                            print(dict["alert_message"] as? String)
                            // ..... and so on
                        }
                    } catch let error as NSError {
                        print("Error: \(error)")
                    }
                }
            } 
Saurabh
  • 745
  • 1
  • 9
  • 33
0

Get the data from [AnyHashable("gcm.notification.data")]

if let aps = userInfo["aps"] as? NSDictionary, let notificationData = userInfo["gcm.notification.data"] as? NSString {

          var dictonary:NSDictionary?
            if let data = notificationData.data(using: String.Encoding.utf8.rawValue) {
                do {
                    dictonary = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary

                    if let alertDictionary = dictonary {
                        print(alertDictionary)
                    }
                } catch{
                    print(error)
                }
piet.t
  • 11,718
  • 21
  • 43
  • 52