Swift: '(NSObject, AnyObject)' does not have a member named 'subscript'

I am trying to extract icon value from userInfo dictionary of remote notification. I read a lot of posts and found a solution to my problem, but I am very unsatisfied!

So here is my data structure (I deleted useless lines): { aps = { badge = 7 } }

To extract this number "7" from my userInfo , I would like to do the following:

 self.updateAppIcon(userInfo["aps"]["badge"] as? Int) 

But of course, I get the following error:

Swift: '(NSObject, AnyObject)' does not have a member named 'subscript'

If I am not mistaken, this is because [] returns AnyObject, which cannot be interpreted as another dictionary.

A working solution would be to do the following:

 func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { if let aps: AnyObject = userInfo["aps"] { if let apsDict = aps as? [String : AnyObject]{ if let badge: AnyObject = apsDict["badge"] { self.updateAppIconBadgeNumber(badge as? Int) } } } } func updateAppIconBadgeNumber(number: Int?) { // do stuff here } 

But seriously ... can I do it more sexually? fewer lines, fewer if clauses, fewer throws, etc.? This is a "code-based" solution to a simple thing.

thanks

+6
source share
2 answers

The shortest of them:

 // Xcode 6.0.1 func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { if let badge = [userInfo["aps"]?["badge"]][0] as? Int { self.updateAppIconBadgeNumber(badge) } } // Xcode 6.1 func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { if let badge = userInfo["aps"]?["badge"] as? Int { self.updateAppIconBadgeNumber(badge) } } 

? between ["aps"] and ["badge"] is called "Optional chain" . You need this because userInfo["aps"] can return nil . And you do not need to point it to [String : AnyObject] , because each AnyObject has an index member.

And, why do we need [ ... ][0] in Xcode 6.0.1, this ... I do not know :(. A mistake, maybe.

+9
source

You can use the nil coleascing statement and make it short, but you may lose readability. If you have one line version of this method,

 func handleRemoteNotification(userInfo: [NSObject : AnyObject]) { if let badge = ((userInfo["aps"] as? [String: AnyObject]) ?? ([String: AnyObject]()))["badge"] as? Int{ self.updateAppIconBadgeNumber(badge) } } 

You can enter [String: AnyObject] types and make it more readable.

 typealias Dict = [String: AnyObject] func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { if let badge = ((userInfo["aps"] as? Dict) ?? Dict())["badge"] as? Int{ self.updateAppIconBadgeNumber(badge) } } 
+3
source

Source: https://habr.com/ru/post/977078/


All Articles