更新到Swift3后的下标问题



我们的服务器端开发人员喜欢给我JSON字符串,它有字典数组的字典数组的字典。真的很愉快....因此,我总是将它们序列化为dict[String:AnyObject],并且在提取对象时简单地对其进行类型转换也没有问题。今天不行!我修正了所有其他错误,当我转换,但这一个对我没有意义,我看了类似的问题,他们的代码不反映我的情况。我只做了2年,所以也许我只是用坏习惯,有人可以打破我的坏习惯。不管怎样,我都很感激你的帮助。

下面是我的一个解析函数的一小段,如果你需要的话,我会给你更多。

func parseRecipes()
{
    if self.avarhub.jsonDICT["recipes"]!.count > 0
    {
        for index in 0..<self.avarhub.jsonDICT["recipes"]!.count
        {
            self.avarhub.recipe.append(self.avarhub.jsonDICT["recipes"]![index]["recipe"] as! String) //the errors all happen on these lines
 //they say ambiguous reference to member 'subscript' or Type 'Any' has no subscript members
        }
    }
    self.tableviewrecipe.reloadData()
}

再次感谢您的帮助。

更多的代码可能会有所帮助?

//data struscture my variable hub
internal struct varhub
{
    //json dictionary
    var jsonDICT = [String:AnyObject]()
    var screenstatus = ""
    var location = ""
    var recipe = [String]()
    var selectedrecipe = ""
}

//this function turns JSON string into a dictionary
func jsonStringToDict(_ text: String) -> [String:AnyObject]?
{
    let data = text.data(using: String.Encoding.utf8)
    do {
        return try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
    }
    catch _ as NSError
    {
        print("error")
    }
    return nil
}

我确实为我的parseRecipe函数使用了vadian的解决方案,我将在许多其他地方吸取教训,但是在我的其他函数项目中有几个地方我仍然必须使用我提出的解决方案,所以我把它放在这里也许它会有所帮助,即使它不像vadian的那么好。

if self.avarhub.jsonDICT["recipes"]!.count > 0
    {
        for index in 0..<self.avarhub.jsonDICT["recipes"]!.count
        {
            let recipes = self.avarhub.jsonDICT["recipes"]! as! Array<Dictionary<String, String>>
            self.avarhub.recipe.append(recipes[index]["recipe"]!)
        }
    }
    self.tableviewrecipe.reloadData()

在Swift 3中,编译器需要知道连续键或索引订阅中所有中间对象的类型,以防止运行时错误。

解决方案是告诉编译器键recipes的值是一个字典数组。

这和你的方法一样,但是没有难看的c风格循环和多余的空检查。

func parseRecipes()
{
    for recipeItem in self.avarhub.jsonDICT["recipes"] as! [[String:Any]] {
        self.avarhub.recipe.append(recipeItem["recipe"] as! String)
    }
    self.tableviewrecipe.reloadData()
}

PS: AnyObject在很多API中被改成了Any,你也可以调整你的代码