view raw
KKG KKG - 7 months ago 109
Swift Question

type any? has no subscript members

I want to get Addresses from profile dictionary,but I got the error "type any? has no subscript members"

var address:[[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
var profile:[String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
profile["Addresses"][0] <-----------------type any? has no subscript members

How can I fix it and get the address? Thanks a lot.


When you subscript profile with "Addresses", you're getting an Any instance back. Your choice to use Any to fix various types within the same array has caused type erasure to occur. You'll need to cast the result back to its real type, [[String: Any]] so that it knows that the Any instance represents an Array. Then you'll be able to subscript it:

func f() {
    let address: [[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
    let profile: [String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]

    guard let addresses = profile["Addresses"] as? [[String: Any]] else {
        // Either profile["Addresses"] is nil, or it's not a [[String: Any]]
        // Handle error here


This is very clunky though, and it's not a very appropriate case to be using Dictionaries in the first place.

In such a situation, where you have dictionaries with a fixed set of keys, structs are a more more appropriate choice. They're strongly typed, so you don't have to do casting up and down from Any, they have better performance, and they're much easier to work with. Try this:

struct Address {
    let address: String
    let city: String
    let zip: Int

struct Profile {
    let name: String
    let age: Int
    let addresses: [Address]

let addresses = [
        address: "someLocation"
        city: "ABC"
        zip: 123
        address: "someLocation"
        city: "DEF"
        zip: 456

let profile = Profile(name: "Mir", age: 10, addresses: addresses)

print(profile.addresses[0]) //much cleaner/easier!