【问题标题】:Importing Firebase causes JSON fetching ambiguous导入 Firebase 导致 JSON 获取不明确
【发布时间】:2019-02-11 15:14:57
【问题描述】:

我一直在我的视图控制器中获取 JSON,我需要一个函数来将同一个 VC 中的数据添加到 firebase,因此导入了 Firebase(Pods firebase core、auth 和 firestore),现在它在获取 JSON 时出现错误这是“下标”的模棱两可的使用

func getDetails(link: URL!) {
    var plot : String = " "

    let task = URLSession.shared.dataTask(with: link!) { (data, response, error) in
        if error != nil
        {
            print("error")
        }
        else
        {
            if let content = data
            {
                do
                {
                    //JSON results
                    let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableLeaves) as AnyObject


           //myJson ~~~ ["Plot"]  Ambiguous use of 'subscript'
                    plot = myJson["Plot"] as! String

                }


                catch
                {
                    print("error in JSONSerialization")
                }
            }
        }
    }
    task.resume()

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
        self.plot.text = plot
    })

}

我希望保持能够选择 JSON 的“Plot”值并让 firebase 运行

【问题讨论】:

  • 我建议从JSONSerialization 移到Codable,这样您就可以获得真正的模型对象,而不必再担心字符串作为下标。通过粘贴 JSON 响应,使用 app.quicktype.io 作为模型对象定义的起点。另外,不要使用计时器来等待结果出来,这就是我们 DispatchGroup 的用途。
  • 为什么要将 json 转换为 AnyObject? ??? as AnyObject - 删除它...
  • @RobertDresler 因为它会说 Type 'Any' has no subscript members
  • @LukasBaranauskas as! [String:Any] 怎么样? ??? (在实际代码中避免强制解包,而是使用例如可选绑定安全地解包)
  • @RobertDresler 谢谢老兄!

标签: json swift firebase google-cloud-firestore


【解决方案1】:

您的问题是将结果从JSONSerialization 转换为AnyObject。如果您希望能够使用下标,在您的情况下,您应该将结果向下转换为字典类型,例如 [String:Any]

if let myJson = try JSONSerialization.jsonObject(with: content, options: .mutableLeaves) as? [String:Any] {
    // plot = myJson["Plot"] as? String ?? "Default value"
}

无论如何,不​​如学习一些关于Codable 的知识并使用它而不是JSONSerialization。只需创建符合Decodable 协议的类/结构,然后使用JSONDecoder 解码Data 对象。

【讨论】:

    【解决方案2】:

    在给定代表服务器响应的ModelObject 结构或类的情况下,我将重写此方法。

    func getDetails(link: URL!) {
        var plot = " "
        let group = DispatchGroup()
    
        group.enter()
        let task = URLSession.shared.dataTask(with: link!) { (data, response, error) in
            defer { group.leave() }
    
            guard error == nil else {
                print(error)
                return
            } 
            if let content = data {
                do {
                    let modelObject = try JSONDecoder().decode(ModelObject.self, from: data)
                    plot = modelObject.plotString
                }
                catch {
                    print(error)
                }
            }
        }
        task.resume()
    
        group.notify(queue: DispatchQueue.main) {
            self.plot.text = plot
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-05
      • 1970-01-01
      • 2017-10-23
      • 2019-05-18
      • 2018-12-18
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多