iosarraysswift3code-migration

ambiguous reference to member subscript after conversion of code from swift 2 to swift 3 in xcode 8


I'm new to swift programming. I am facing this issue after updating this code from swift 2 to swift 3

Swift 2 code was

let dicConversation = self.conversationListArray?[indexPath.row] as! NSMutableDictionary 

now I converted successfully this code in swift 3 by splitting it into parts

Swift 3 code

let accountArrayDict = self.conversationListArray?[indexPath.row] as? Dictionary<String, Any>
let accountArray : [String : String] = accountArrayDict?["accounts"] as! [String : String]

code successfully converted in swift 3 but I don't know how to convert this line below:

cell.conversationTitle?.text = accountArray?[0]["displayName"] as? String
        

below this is what I have tried but showing error in first part. Second one is now okay

cell.conversationTitle?.text = accountArray[0] as![String]
let accountArray : [String] = accountArrayDict?["displayName"] as! [String]

Solution

  • First of all, never declare data source arrays for (non-optional) table views as optional.

    var conversationListArray = [[String:Any]]()
    

    This avoids a lot of question marks and type casts,
    the compiler knows accountArrayDict is [String:Any]

    let accountArrayDict = self.conversationListArray[indexPath.row]
    

    The name accountArray implies that the type is an array so it's

    let accountArray = accountArrayDict["accounts"] as! [[String : String]]
    

    Then you can write

    cell.conversationTitle?.text = accountArray[0]["displayName"]
    

    Since the compiler knows that the inner dictionary has String values you get rid of this type cast, too. That's a good example why Swift native types are much more efficient than Foundation NS(Mutable)... collection types.

    Nevertheless for a nested data model like this it's highly recommended to use a custom struct or class.