加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在Swift中解析json,AnyObject类型

发布时间:2020-12-14 06:04:35 所属栏目:百科 来源:网络整理
导读:我试图解析一个json,但我有一些困难的数据类型,特别是AnyObject类型downcasting。 让我们考虑下面的json(它是一个完整的json的提取)。 { "weather": [ { "id":804,"main":"Clouds","description":"overcast clouds","icon":"04d" } ],} 对我来说,json可以
我试图解析一个json,但我有一些困难的数据类型,特别是AnyObject类型downcasting。

让我们考虑下面的json(它是一个完整的json的提取)。

{  "weather":
   [
      {
         "id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"
      }
   ],}

对我来说,json可以描述如下:

- json: Dictionary of type [String: AnyObject] (or NSDictionary,so = [NSObject,AnyObject] in Xcode 6 b3)
    - "weather": Array of type [AnyObject] (or NSArray)
         - Dictionary of type [String: AnyObject] (or NSDictionary,AnyObject] in Xcode 6 b3)

我的json是AnyObject类型的! (我使用JSONObjectWithData从URL获取JSON)。

然后我想访问天气词典。这里是我写的代码。

var localError: NSError?
var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data,options: NSJSONReadingOptions.MutableContainers,error: &localError)

if let dict = json as? [String: AnyObject] {
 if let weatherDictionary = dict["weather"] as? [AnyObject] {
      // Do stuff with the weatherDictionary
    }
}

这是我得到的错误

Playground execution failed: error: <EXPR>:28:56: error: '[AnyObject]' is not a subtype of '(String,AnyObject)'
        if let weatherDictionary = dict["weather"] as? [AnyObject] {

我不明白为什么dict [“weather”]与(String,AnyObject)的子类型比较而不是AnyObject。

我声明我的字典为[String:AnyObject],所以我使用String键访问一个值,我应该有一个AnyObject,没有?

如果我使用NSDictionary而不是[String:AnyObject],它的工作原理。

如果我使用NSArray而不是[AnyObject],它的工作原理。

- The Xcode 6 beta 3 release notes tell that "NSDictionary* is now imported from Objective-C APIs as [NSObject : AnyObject].".
- And the Swift book: "When you bridge from an NSArray object to a Swift array,the resulting array is of type [AnyObject]."

编辑

我忘了强行解开dict [“天气”]!

if let dict = json as? [String: AnyObject] {
    println(dict)
       if let weatherDictionary = dict["weather"]! as? [AnyObject] {
            println("nWeather dictionary:nn(weatherDictionary)")
            if let descriptionString = weatherDictionary[0]["description"]! as? String {
                println("nDescription of the weather is: (descriptionString)")
        }
    }
}

注意,我们应该仔细检查第一个Optional的存在。

if let dict = json as? [String: AnyObject] {
    for key in ["weather","traffic"] {
        if let dictValue = dict[key] {
            if let subArray = dictValue as? [AnyObject] {
                println(subArray[0])
            }
        } else {
            println("Key '(key)' not found")
        }
    }
}
这对我在操场和终端使用env xcrun swift工作得很好

UPDATED FOR SWIFT 3.0

我更新了Swift 3的代码,还展示了如何将解析的JSON包装到对象中。感谢所有的投票!

import Foundation

struct Weather {
    let id: Int
    let main: String
    let description: String
    let icon: String
}

extension Weather {
    init?(json: [String: Any]) {
        guard
            let id = json["id"] as? Int,let main = json["main"] as? String,let description = json["description"] as? String,let icon = json["icon"] as? String
        else { return nil }
        self.id = id
        self.main = main
        self.description = description
        self.icon = icon
    }
}

var jsonStr = "{"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],}"

enum JSONParseError: Error {
    case notADictionary
    case missingWeatherObjects
}

var data = jsonStr.data(using: String.Encoding.ascii,allowLossyConversion: false)
do {
    var json = try JSONSerialization.jsonObject(with: data!,options: [])
    guard let dict = json as? [String: Any] else { throw JSONParseError.notADictionary }
    guard let weatherJSON = dict["weather"] as? [[String: Any]] else { throw JSONParseError.missingWeatherObjects }
    let weather = weatherJSON.flatMap(Weather.init)
    print(weather)
}
catch {
    print(error)
}

– 上一个答案 –

import Foundation

var jsonStr = "{"weather":[{"id":804,}"
var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding,allowLossyConversion: false)
var localError: NSError?
var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data!,error: &localError)

if let dict = json as? [String: AnyObject] {
    if let weather = dict["weather"] as? [AnyObject] {
        for dict2 in weather {
            let id = dict2["id"]
            let main = dict2["main"]
            let description = dict2["description"]
            println(id)
            println(main)
            println(description)
        }
    }
}

因为我仍然拿起来投票的这个答案,我想我会重新审视它的Swift 2.0:

import Foundation

var jsonStr = "{"weather":[{"id":804,allowLossyConversion: false)
do {
    var json = try NSJSONSerialization.JSONObjectWithData(data!,options: NSJSONReadingOptions.MutableContainers)

    if let dict = json as? [String: AnyObject] {
        if let weather = dict["weather"] as? [AnyObject] {
            for dict2 in weather {
                let id = dict2["id"] as? Int
                let main = dict2["main"] as? String
                let description = dict2["description"] as? String
                print(id)
                print(main)
                print(description)
            }
        }
    }

}
catch {
    print(error)
}

最大的区别是变量json不再是可选类型和do / try / catch语法。我也去了键入id,main和description。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读