【问题标题】:Compiler error when casting Dictionary to AnyObject?将 Dictionary 转换为 AnyObject 时出现编译器错误?
【发布时间】:2014-11-03 16:08:33
【问题描述】:

我正在尝试在 Swift 中进行一个简单的扩展,以便使用 NSJSONSerialization.dataWithJSONObject 轻松将 Dictionary 转换为 JSON NSData。

extension Dictionary {
    func toJSONData() -> NSData! {
        return NSJSONSerialization.dataWithJSONObject(self, options: nil, error: nil)
    }
}

我不太明白为什么这不会编译。它给了我一个类型错误:

Cannot downcast from 'Dictionary<Key, Value>' to non-@objc protocol type 'AnyObject'

有什么想法吗?我用谷歌搜索了一下,找不到任何东西。

注意:

我已经对此进行了测试,效果很好:

return NSJSONSerialization.dataWithJSONObject(["":""], options: nil, error: nil)

【问题讨论】:

  • 问题是不是所有的 Swift 字典都可以转换为AnyObject,只有[NSObject: AnyObject] 类型的。并且定义仅适用于某些受限泛型类型的泛型类型的扩展似乎是不可能的(数组扩展有类似的问答)。
  • @MartinR 是的,在玩了一会儿之后,我意识到我正在扩展 Dictionary 而不是 NSDictionary。将其放入答案中,我会接受。

标签: ios swift casting nsjsonserialization


【解决方案1】:

(来自我上面的评论:) 问题是并非所有 Swift 字典都可以转换为 AnyObject,只有 [NSObject: AnyObject] 类型的字典可以转换为 AnyObject。并且定义仅适用于某些受限泛型类型的泛型类型的扩展似乎是不可能的(数组扩展有类似的问答)。

您可以使用一个函数(正如 Nate 在他的回答中所建议的那样),或者定义一个扩展 改为NSDictionary。


Swift 2 更新:从 Swift 2 开始,您可以定义仅适用于某些受限泛型类型的泛型类型的扩展:

extension Dictionary where Key : NSObject, Value : AnyObject {
    func toJSONData() -> NSData! {
        return try? NSJSONSerialization.dataWithJSONObject(self, options: [])
    }
}

然后

let d1 = ["foo" : "bar"].toJSONData()

按预期编译和工作,但是

struct Bar {} 
let d2 = [ "foo" : Bar() ].toJSONData()

无法编译,因为 Bar() 不是 AnyObject。

【讨论】:

    【解决方案2】:

    编译器抱怨是因为Dictionary(以其泛型形式)理论上可以容纳不可桥接的类型,例如 Swift 枚举。您可以通过这种方式定义顶级函数并对字典的键和值类型施加约束:

    func toJSONData<T1: _ObjectiveCBridgeable, T2: _ObjectiveCBridgeable>(dict: [T1: T2]) -> NSData! {
        return NSJSONSerialization.dataWithJSONObject(dict, options: nil, error: nil)
    }
    

    【讨论】:

      【解决方案3】:

      您是否考虑过扩展 NSData? 生成的代码非常简洁:

      extension NSData {
          convenience init(jsonDictionary: [String:AnyObject]) throws {
              self.init(data:
                  try NSJSONSerialization.dataWithJSONObject (
                      jsonDictionary,
                      options: NSJSONWritingOptions(rawValue: 0)
                  ))
          }
      }
      

      用法:

      let jsonData = try NSData(jsonDictionary: ["foo": 313, "fee": "bar"])
      

      【讨论】:

        【解决方案4】:
        func simplePostMethod()  
        {
        
        let url : URL = URL(string: "writ your URL here")!
        
        var request = URLRequest(url: url)
        
        let session = URLSession.shared
        
        request.httpMethod = "POST"
        
        
        // Below are input parameter, you can put your input parameter.
        
         let params = ["name":"hijk", "nickname":"hijk","password":"123456","gender":"male","dob":"1989-02-28","email":"hijk@gmail.com","device_id":"sffdg5645445","os":"ios","social_id":"sdjaljdlasldklsdsdls"] as Dictionary<String, String>
        
        
                do{
                    request.httpBody =  try JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions.prettyPrinted)
                }
                catch
                {
        
                }
                request.addValue("application/json", forHTTPHeaderField: "Content-Type")
                request.addValue("application/json", forHTTPHeaderField: "Accept")
                let  task = session.dataTask(with: request, completionHandler: {(data,response,error) in
        
        
                    if (data != nil)
                    {
                        do{
                            let dict =  try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableLeaves)
                            print(dict);
                        }
                        catch
                        {
        
                        }
        
                    }
        
                }
                )
        
                task.resume()
            }
        

        【讨论】:

          猜你喜欢
          • 2020-11-14
          • 1970-01-01
          • 1970-01-01
          • 2017-10-25
          • 1970-01-01
          • 1970-01-01
          • 2016-10-05
          • 2019-10-30
          • 2017-02-01
          相关资源
          最近更新 更多