使用 SwiftyJSON 将 JSON 解析为结构

Parsing JSON to a struct with SwiftyJSON

我有一个简单的结构来处理来自 SwiftyJSON 的数据解析

struct Threads{
    var threads:[ThreadDetail]
}

struct ThreadDetail {
    var title:String
    var username:String
    var prefix_id:Int
}

这是 API 响应的示例

{
    "threads": [
        {
            "first_post_id": 258535,
            "prefix_id": 1,
            "thread_id": 50204,
            "title": "Testing board title",
            "user_id": 20959,
            "username": "test",
            "view_count": 247,
        }

下面是我想不通的部分

        Alamofire.request(url, method: .get, headers: headers).validate().responseJSON { response in
            switch response.result {
            case .success(let value):
                let json = JSON(value)
                for item in json["threads"].arrayValue {

                    //how should it be written here?

                }
            case .failure(let error):
                print(error)
            }
        }
    }
}

你可以按照我记得的 SwiftyJSON 来完成:

Alamofire.request(url, method: .get, headers: headers).validate().responseJSON { response in
        switch response.result {
        case .success(let value):
            let json = JSON(value)
            var models = [ThreadDetail]()
            for item in json["threads"].arrayValue {
                let model = ThreadDetail(title: item["title"].stringValue,
                                         username: item["username"].stringValue,
                                         prefix_id: item["prefix_id"].intValue)
                models.append(model)
            }
            // do whatever you need with models
        case .failure(let error):
            print(error)
        }
    }

但实际上,正如 Frankenstein 所说,解决问题的最佳方法就是使模型符合 Codable。

声明您的模型并使其符合 Codable。

struct Response: Codable {
    let threads: [Thread]
}

// MARK: - Thread
struct Thread: Codable {
    let firstPostID, prefixID, threadID: Int
    let title: String
    let userID: Int
    let username: String
    let viewCount: Int

    enum CodingKeys: String, CodingKey {
        case firstPostID = "first_post_id"
        case prefixID = "prefix_id"
        case threadID = "thread_id"
        case title
        case userID = "user_id"
        case username
        case viewCount = "view_count"
    }
}

之后,使用JSON解码器将数据转换为模型

  Alamofire.request(urlString).response {
            response in
            guard let data = response.data else { return }
            do {
                let decoder = JSONDecoder()
                let threadsWrapper = try decoder.decode(Response.self, from: data)
            } catch let error {
                print(error)
            }

使用此网站将您的 JSON 转换为 Codable https://app.quicktype.io/

我个人使用我为使用 JSON 的应用程序定制的库,名为 Weave。它建立在 NSURLSession 之上,完全原生 Swift。当您使用 WVRequest.request() 创建请求时,对于参数 outputType,请使用类型 .json.

这是使用 Wea​​ve 的上述代码:

WVRequest.start(url, requestType: .get, outputType:.json, headers: headers).start() { response in

    if response.success {
        // Cast to a dictionary
        let json = (response as! WVJSONResponse).json as! [String:Any]
        let threads = json["threads"] as! [Thread]
        // From here, just use a for loop, and create an instance of your Thread class for each iteration.
    } else {
       print("Error!")
    }

}

希望对您有所帮助!

struct Temperature: Codable {
    let high: Double
    let low: Double
}


struct Bluh: Codable, Identifiable {
    var temperature: JSON
    func getTemperatures() -> Temperature? {
        do {
            let decoder = JSONDecoder()
            return try decoder.decode(Temperature.self, from: temperature.rawData())
        } catch let error {
            print(error)
        }
    }
}

你也可以这样做。如果您的数据是 SWIFT JSON 并尝试转换为结构。