Swift 2 到 Swift 3 迁移:对成员“下标”的模糊引用

Posted

技术标签:

【中文标题】Swift 2 到 Swift 3 迁移:对成员“下标”的模糊引用【英文标题】:Swift 2 to Swift 3 migration: Ambiguous reference to member 'subscript' 【发布时间】:2016-10-05 15:00:10 【问题描述】:

我有一段从 youtube API 解析 JSON 的代码。接收到的 JSON 对象存储在字典中,然后 JSON 对象项的子数组存储在 item 中。 Xcode 给我一个错误,上面写着:"items" is an ambiguous reference to member subscript for JSON and i for item[i].

我阅读了一些关于 stack-overflow 的帖子,解决了类似的问题,其中说 Swift 3 将类型更改为 [String: AnyObject],但这对我也不起作用。

    do
        
            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! Dictionary<NSObject, AnyObject>
            //print(json)
            let item: Array<Dictionary<NSObject,AnyObject>> = json["items"] as! Array<Dictionary<NSObject,AnyObject>>

            for i in 0 ..< item.count
            
                let snippetDict = (item[i] as Dictionary<NSObject, AnyObject>)["snippet"] as! Dictionary<NSObject, AnyObject>

                // Initialize a new dictionary and store the data of interest.
                var desiredVideoDict = Dictionary<NSObject, AnyObject>()

                desiredVideoDict["title"] = snippetDict["title"]
                desiredVideoDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<NSObject, AnyObject>)["default"] as! Dictionary<NSObject, AnyObject>)["url"]
                desiredVideoDict["videoID"] = (snippetDict["resourceId"] as! Dictionary<NSObject, AnyObject>)["videoId"]

                // Append the desiredPlaylistItemDataDict dictionary to the videos array.
                //self.videosArray.append(desiredPlaylistItemDataDict)

                // Reload the tableview.
                self.tblVideos.reloadData()

感谢您的时间和帮助。

【问题讨论】:

您能解决问题吗? 【参考方案1】:

标准 JSON 字典在 Swift 3 中的类型为 [String:Any]

我建议使用类型别名以获得更好的易读性。

typealias JSONObject = [String:Any]

现在您可以用这种方式编写代码(我还更改了 for 循环语法)

do

  let json = try JSONSerialization.jsonObject(with: data!, options: []) as! JSONObject
  //print(json)
  let items  = json["items"] as! Array<JSONObject>

  for item in items
  
    let snippetDict = item["snippet"] as! JSONObject

    // Initialize a new dictionary and store the data of interest.
    var desiredVideoDict = JSONObject()

    desiredVideoDict["title"] = snippetDict["title"]
    desiredVideoDict["thumbnail"] = ((snippetDict["thumbnails"] as! JSONObject)["default"] as! JSONObject)["url"]
    desiredVideoDict["videoID"] = (snippetDict["resourceId"] as! JSONObject)["videoId"]

    // Append the desiredPlaylistItemDataDict dictionary to the videos array.
    //self.videosArray.append(desiredPlaylistItemDataDict)

    // Reload the tableview.

  
  self.tblVideos.reloadData()
...

mutableContainers 根本不需要。

【讨论】:

【参考方案2】:

这对我有用:

    do
    
        let json = try JSONSerialization.jsonObject(with: data , options: .mutableContainers) as! Dictionary<String, AnyObject>
        //print(json)
        let item = json["items"] as! Array<Dictionary<String,AnyObject>>

        for i in 0 ..< item.count
        
            let snippetDict = item[i]["snippet"] as! Dictionary<String, AnyObject>
            // Initialize a new dictionary and store the data of interest.
            var desiredVideoDict = Dictionary<String, AnyObject>()

            desiredVideoDict["title"] = snippetDict["title"]
            desiredVideoDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
            desiredVideoDict["videoID"] = (snippetDict["resourceId"] as! Dictionary<String, AnyObject>)["videoId"]

            // Reload the tableview.
            self.tblVideos.reloadData()
        
    catch
        print("parse error")
    

【讨论】:

我认为解释这个问题可能有助于 OP 理解他做错了什么。

以上是关于Swift 2 到 Swift 3 迁移:对成员“下标”的模糊引用的主要内容,如果未能解决你的问题,请参考以下文章

对成员 Swift 3 的模糊引用

Swift 3.0:对成员“下标”问题的模糊引用

从 Swift 2.3 迁移到 Swift 3 错误消息

从 swift 2.3 问题迁移到 swift 3.1

Swift 2.3 到 Swift 3.1 迁移 - Alamofire 请求错误

NSData init?(contentsOf url: URL) 从 Swift 2 迁移到 Swift 3