一尘不染

Swift 3中的JSON解析

swift

有没有人能够找到一种在Swift
3中解析JSON文件的方法?我已经能够获得返回的数据,但是在将数据分解为特定字段方面我没有成功。我会发布示例代码,但是我经历了很多不同的方法,但是都没有成功。我想解析的基本格式是这样的。提前致谢。

{
  "Language": {

    "Field":[
          {
          "Number":"976",
          "Name":"Test"
          },
          {
          "Number":"977",
          "Name":"Test"
          }
       ]
   }
}

阅读 276

收藏
2020-07-07

共1个答案

一尘不染

你试过了JSONSerialization.jsonObject(with:options:)吗?

var jsonString = "{" +
    "\"Language\": {" +
    "\"Field\":[" +
    "{" +
    "\"Number\":\"976\"," +
    "\"Name\":\"Test\"" +
    "}," +
    "{" +
    "\"Number\":\"977\"," +
    "\"Name\":\"Test\"" +
    "}" +
    "]" +
    "}" +
    "}"

var data = jsonString.data(using: .utf8)!

let json = try? JSONSerialization.jsonObject(with: data)

Swift有时会产生一些非常奇怪的语法。

if let number = json?["Language"]??["Field"]??[0]?["Number"] as? String {
    print(number)
}

JSON对象层次结构中的所有内容最终都被包装为可选(即AnyObject?)。Array<T>下标返回一个非可选的T。对于此JSON(包装在可选的数组下标中),返回Optional<AnyObject>。但是,Dictionary<K, V>下标返回Optional<V>。对于此JSON,下标返回非常奇怪的外观
Optional<Optional<AnyObject>>(即AnyObject??)。

  • json是一个Optional<AnyObject>
  • json?["Language"]返回Optional<Optional<AnyObject>>
  • json?["Language"]??["Field"]返回Optional<Optional<AnyObject>>
  • json?["Language"]??["Field"]??[0]返回Optional<AnyObject>
  • json?["Language"]??["Field"]??[0]?["Number"]返回Optional<Optional<AnyObject>>
  • json?["Language"]??["Field"]??[0]?["Number"] as? String返回Optional<String>

Optional<String>,然后由使用if let语法产物String


最后说明:迭代字段数组如下所示。

for field in json?["Language"]??["Field"] as? [AnyObject] ?? [] {
    if let number = field["Number"] as? String {
        print(number)
    }
}

Swift 4更新

Swift 4使这一切变得更容易处理。再次,我们将从您的测试数据开始("""使它变得更好)。

let data = """
{
  "Language": {

    "Field":[
          {
          "Number":"976",
          "Name":"Test"
          },
          {
          "Number":"977",
          "Name":"Test"
          }
       ]
   }
}
""".data(using: .utf8)!

接下来,我们可以围绕JSON中使用的对象定义类。

struct Object: Decodable {
    let language: Language
    enum CodingKeys: String, CodingKey { case language="Language" }
}

struct Language: Decodable {
    let fields: [Field]
    enum CodingKeys: String, CodingKey { case fields="Field" }
}

struct Field: Decodable {
    let number: String
    let name: String
    enum CodingKeys: String, CodingKey { case number="Number"; case name="Name" }
}

CodingKeys枚举是结构特性如何映射到JSON对象构件字符串。该映射由来自动完成Decodable


现在解析JSON很简单。

let object = try! JSONDecoder().decode(Object.self, from: data)

print(object.language.fields[0].name)

for field in object.language.fields {
    print(field.number)
}
2020-07-07