Swift error when trying to access Dictionary: `Could not find member 'subscript'`
Let's take a look at
response["current_rates"][exchange][currency]
response
is declared as Dictionary<String,Any>()
, so after the first subscript you try to call another two subscripts on an object of type Any.
Solution 1. Change the type of response to be a nested dictionary. Note that I added the question marks because anytime you access a dictionary item you get back an optional.
var response = Dictionary<String,Dictionary<String,Dictionary<String, Float>>>()
func valueForCurrency(currency :String, exchange :String) -> Float? {
return response["current_rates"]?[exchange]?[currency]
}
Solution 2. Cast each level to a Dictionary as you parse. Make sure to still check if optional values exist.
var response = Dictionary<String,Any>()
func valueForCurrency(currency :String, exchange :String) -> Float? {
let exchanges = response["current_rates"] as? Dictionary<String,Any>
let currencies = exchanges?[exchange] as? Dictionary<String,Any>
return currencies?[currency] as? Float
}
Why do I get this error in Swift Could not find member subscript
I suspect your problem is that result
is an optional type. option-click on the result
variable. If it is of type NSDictionary?
or something like [NSObject: AnyObject]?
then result
will have to be unwrapped before you can use it. I would first try:
if let location = result?["location"]?["name"] as? String {
//do something
}
If result
is AnyObject
or AnyObject?
, I would suggest taking this a step at a time:
if let dict = result as? NSDictionary {
if let location = dict["location"] as? NSDictionary {
if let name = location["name"] as? String {
// use name
}
}
}
You can compact the above into a single if:
if let name = ((result as? NSDictionary)?["location"] as? NSDictionary)?["name"] as? String {
// use name
}
Type 'Any' has no subscript members when accessing dictionary in UserDefaults
The reason of showing this error in your code is: the compiler cannot recognize result
as dictionary, if you tried to option and click on result
you would see that its type is Any
. You have to cast it first as [String: AnyObject]
and then get "Authorities" form it.
It should be like this:
if let result = UserDefaults.standard.dictionary(forKey: "dict") {
print(result)
}
That's how you should "optional binding" the dictionary, thus (assumeing that "Authorities" is a [String: String]
):
if let addresses = result["Authorities"] as? [String: String] {
print(addresses)
}
You could also do it as one step:
if let result = UserDefaults.standard.dictionary(forKey: "dict"),
let addresses = result["Authorities"] as? [String: String] {
print(result)
print(addresses)
let levelAccess = addresses["levelAccess"]
print(levelAccess) // optional
}
Finally, you could get the levelAcess
from addresses
as:
let levelAccess = addresses["levelAccess"]
Again, note that levelAccess
would be an optional
string (String?
), which means you should also handle it.
Swift Dictionary access value through subscript throws Error
Issue is solved by explicitly specifying the Type
of objects the array contains, In my case it was Array<[String:Any]>
if let detailsObj = dictionary[Keys.details] as? Array<[String:Any]> { //we should also specify what type is present inside Array
}
Credits: @Hamish, @Dávid Pásztor
Thanks!
In Swift getting error Ambiguous reference to member 'subscript'
try to cast keyValue
to Key. For example:
extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject {
func getValueForKeyPath(keyValue : String) -> String{
return ((self[keyValue as! Key] as? Dictionary<String,String>) ?? ["":""])?["text"] ?? ""
}
}
type 'Any' has no subscript members
snapshot.value
has a type of Any
. A subscript is a special kind of function that uses the syntax of enclosing a value in braces. This subscript function is implemented by Dictionary
.
So what is happening here is that YOU as the developer know that snapshot.value
is a Dictionary
, but the compiler doesn't. It won't let you call the subscript
function because you are trying to call it on a value of type Any
and Any
does not implement subscript
. In order to do this, you have to tell the compiler that your snapshot.value
is actually a Dictionary
. Further more Dictionary
lets you use the subscript function with values of whatever type the Dictionary
's keys are. So you need to tell it you have a Dictionary
with keys as String
(AKA [String: Any]
). Going even further than that, in your case, you seem to know that all of the values in your Dictionary
are String
as well, so instead of casting each value after you subscript it to String
using as! String
, if you just tell it that your Dictionary
has keys and values that are both String
types (AKA [String: String]
), then you will be able to subscript to access the values and the compiler will know the values are String
also!
guard let snapshotDict = snapshot.value as? [String: String] else {
// Do something to handle the error
// if your snapshot.value isn't the type you thought it was going to be.
}
let employerName = snapshotDict["employerName"]
let employerImage = snapshotDict["employerImage"]
let uid = snapshotDict["fid"]
And there you have it!
Swift Subscript Error
NSDictionary accessed from Swift is an interesting beast.
As long as Swift only knows something is an NSDictionary (not a more specific [Key: Value]
Swift-style dictionary), you can only retrieve AnyObject?
s out of it.
let dictTemp: NSDictionary = // from somewhere...
let step1 = dictTemp[0] // step1 is an AnyObject?
But then, since you've imported Foundation, you can keep going with a magical subscript operator that works on AnyObject
, and checks whether the thing is a dictionary:
let step2 = step1?["source"] // step2 is any AnyObject??
Here's where it gets interesting, because
- if
step1
was a dictionary with a "source" key inside it,step2
will be the corresponding value. - if
step1
was a dictionary without a "source" key,step2
will benil
— in particular, it'sAnyObject??.Some(AnyObject?.None)
. - if
step1
was nil (the original dictionary didn't have 0 as a key), or not a dictionary (it had a 0 key with some other kind of value), thenstep2
will benil
— in particular,AnyObject??.None
.
(The distinction between the last 2 cases is mostly unimportant and you shouldn't worry about it, but if you're interested you can see it by using dump
).
And of course, we can apply the same principle again:
let step3 = step2??["sourceUrl"] // step3 is AnyObject?? again
Now, binding them all in one if
:
if let url = dictTemp[0]?["source"]??["sourceUrl"] as? String {
// do something with url...
}
Caveat
This type of syntax can be dangerous, since it works with arrays and dictionaries at the same time. What would you expect in these situations?
let dict: NSDictionary = [0: ["source": [3: "result"]]]
dict[0]?["source"]??[3] // returns nil (surprise!)
dict[0]?["source"]??[3 as NSNumber] // returns "result"
let dict2: NSDictionary = [0: ["source": [8, 7, 6, 5, 4]]]
dict2[0]?["source"]??[3] // returns 5
dict2[0]?["source"]??[3 as NSNumber] // returns nil (surprise!)
Access to Dictionary values inside Array in swift
println(menuItems[0]["data"]!["name"])
Short answer: menuItems[0]["data"] returns an optional dictionary.
You can look at the below REPL output to understand the issue.
- sets up the object.
- shows that the array returns a regular dictionary. If the index is out of range, an error will be thrown instead of returning an optional dictionary.
- shows that accessing a key in a dictionary that does not exist will return nil
- shows that accessing a key in a dictionary will return an optional of its value type. For instance, if a dictionary is storing Strings in its values, it will return a String? when indexed into.
- shows that we cannot use subscripts on an optional dictionary.
- shows that we can force the optional dictionary to be a dictionary because we know it is not nil. The REPL shows us that the new return type is
Dictionary<String, String>
- shows that we can then use subscripts to get at the innermost values, and this returns an optional string to us. Optional strings are printable, so my code above doesn't need a second
!
. - shows that if we force both dictionary return types to their non-optional types, we get a regular value back (a string).
In real code, you would probably want to check for optionals, and handle nils accordingly.
1> let menu: Dictionary<String, Dictionary<String, String>>[]
= [["dict1" : ["key" : "val"]], ["dict2" : ["key" : "val"]]]
menu: Dictionary<String, Dictionary<String, String>>[] = size=2 {
[0] = {
[0] = {
key = "dict1"
value = {
[0] = {
key = "key"
value = "val"
}
}
}
}
[1] = {
[0] = {
key = "dict2"
value = {
[0] = {
key = "key"
value = "val"
}
}
}
}
}
2> menu[0]
$R1: Dictionary<String, Dictionary<String, String>> = {
[0] = {
key = "dict1"
value = {
[0] = {
key = "key"
value = "val"
}
}
}
}
3> menu[0]["key"]
$R2: Dictionary<String, String>? = nil
4> menu[0]["dict1"]
$R3: Dictionary<String, String>? = Some {
[0] = {
key = "key"
value = "val"
}
}
5> menu[0]["dict1"]["key"]
REPL:6:1: error: could not find member 'subscript'
menu[0]["dict1"]["key"]
^~~~~~~~~~~~~~~~~~~~~~~
6> menu[0]["dict1"]!
$R4: Dictionary<String, String> = {
[0] = {
key = "key"
value = "val"
}
}
7> menu[0]["dict1"]!["key"]
$R5: String? = "val"
8> menu[0]["dict1"]!["key"]!
$R6: String = "val"
Related Topics
How to Setup Viewcontroller in Playgrounds
How to Use Swift Flatmap to Filter Out Optionals from an Array
How to Check If a String Contains Chinese in Swift
Get an Error When Trying to Get All the Photos from Phassetcollection.Fetchassetcollections
How to Loop Through All MAC Desktop Spaces
Giving Physics to Tiles of Sktilemapnode in Xcode 8
Passing Data Between Two Nsoperations
Swift 2.0, Alamofire: Set Cookies in Http Post Request
Convert Swiftui View to Nsimage
Adding Activity Indicator to Uialertview
What's the Swift Equivalent of Objective-C's "#Ifdef _Iphone_11_0"
How to Prove "Copy-On-Write" on String Type in Swift
Convert or Cast Object to String
Adding Nscoding as an Extension
How to Convert Nsset to [String] Array
Create PDF of Dynamic Size with Typography Using Uiview Template(S)