在swift

时间:2017-05-05 18:56:16

标签: json swift

我是Swift编程的新手,我遇到了json字符串解析的问题。我的json字符串格式如下:

{
  "fileName": "test",
  "display": "test",
  "children": [
    {
      "fileName": "test2",
      "display": "test2",
      "children": [
        {
          "fileName": "test3",
          "display": "test3",
          "children": [
            {
              "fileName": "test4",
              "display": "test4"
            }
          ]
        }
      ]
    }
  ]
}

我想解析这个以列出具有struct parent和child的Dataobject,但直到现在都没有成功。我的代码如下:

儿童模特:

import Foundation
public struct Children {
    public let fileName: String
    public let display: String
    public let children: [Children]

    public init(lat: String, long: String, hourData: [Children]) {
        self.fileName = lat
        self.display = long
        self.children = hourData
    }   
}

extension Children: JSONDecodable {
    public init(decoder: JSONDecoder) throws {
        self.fileName = try decoder.decode(key: "fileName")
        self.display = try decoder.decode(key: "display")
        self.children = try decoder.decode(key: "children")
    }
}

import Foundation
public protocol JSONDecodable {   
    init(decoder: JSONDecoder) throws      
}

public enum JSONDecoderError: Error {
    case invalidData
    case keyNotFound(String)
    case keyPathNotFound(String)
}

public struct JSONDecoder {

    typealias JSON = [String: AnyObject]

    // MARK: - Properties
    private let JSONData: JSON

    // MARK: - Static Methods
    public static func decode<T: JSONDecodable>(data: Data) throws -> T {
        let decoder = try JSONDecoder(data: data)
        return try T(decoder: decoder)
    }

    // MARK: - Initialization
    public init(data: Data) throws {
        if let JSONData = try JSONSerialization.jsonObject(with: data, options: []) as? JSON {
            self.JSONData = JSONData
        } else {
            throw JSONDecoderError.invalidData
        }
    }

    // MARK: -
    private init(JSONData: JSON) {
        self.JSONData = JSONData
    }

    // MARK: - Public Interface
    func decode<T>(key: String) throws -> T {
        if key.contains(".") {
            return try value(forKeyPath: key)
        }

        guard let value: T = try? value(forKey: key) else { throw JSONDecoderError.keyNotFound(key) }
        return value
    }

    func decode<T: JSONDecodable>(key: String) throws -> [T] {
        if key.contains(".") {
            return try value(forKeyPath: key)
        }

        guard let value: [T] = try? value(forKey: key) else { throw JSONDecoderError.keyNotFound(key) }
        return value
    }

    // MARK: - Private Interface
    private func value<T>(forKey key: String) throws -> T {
        guard let value = JSONData[key] as? T else { throw JSONDecoderError.keyNotFound(key) }
        return value
    }

    private func value<T: JSONDecodable>(forKey key: String) throws -> [T] {
        if let value = JSONData[key] as? [JSON] {
            return try value.map({ (partial) -> T in
                let decoder = JSONDecoder(JSONData: partial)
                return try T(decoder: decoder)
            })
        }

        throw JSONDecoderError.keyNotFound(key)
    }

    // MARK: -
    private func value<T>(forKeyPath keyPath: String) throws -> T {
        var partial = JSONData
        let keys = keyPath.components(separatedBy: ".")

        for i in 0..<keys.count {
            if i < keys.count - 1 {
                if let partialJSONData = JSONData[keys[i]] as? JSON {
                    partial = partialJSONData
                } else {
                    throw JSONDecoderError.invalidData
                }

            } else {
                return try JSONDecoder(JSONData: partial).value(forKey: keys[i])
            }
        }

        throw JSONDecoderError.keyPathNotFound(keyPath)
    }

    private func value<T: JSONDecodable>(forKeyPath keyPath: String) throws -> [T] {
        var partial = JSONData
        let keys = keyPath.components(separatedBy: ".")

        for i in 0..<keys.count {
            if i < keys.count - 1 {
                if let partialJSONData = JSONData[keys[i]] as? JSON {
                    partial = partialJSONData
                } else {
                    throw JSONDecoderError.invalidData
                }

            } else {
                return try JSONDecoder(JSONData: partial).value(forKey: keys[i])
            }
        } 
        throw JSONDecoderError.keyPathNotFound(keyPath)
    }
}

请帮我解决这个问题。

0 个答案:

没有答案