bondgaide
bondgaide

Reputation: 85

Parsing JSON to a struct with SwiftyJSON

I have a simple struct to handle the data parsing from the SwiftyJSON

struct Threads{
    var threads:[ThreadDetail]
}

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

Here's a sample of the API response

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

Now here's the part where I couldn't figure out how

        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)
            }
        }
    }
}

Upvotes: 1

Views: 1589

Answers (4)

Stephen Lee
Stephen Lee

Reputation: 327

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)
        }
    }
}

You can do sth like tis too. If your data is SWIFY JSON and trying to convert to struct.

Upvotes: 0

Jackson Zamorano
Jackson Zamorano

Reputation: 403

I personally use a library I custom made for apps that use JSON called Weave. It's built on top of NSURLSession and fully native Swift. When you create a request using WVRequest.request(), for the argument outputType, use the type .json.

Here's your above code using Weave:

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!")
    }

}

Hope that helps!

Upvotes: 0

Andrew
Andrew

Reputation: 915

Declare your models and conform them 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"
    }
}

After that, convert your data to model by using JSONDecoder

  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)
            }

Use this website to convert your JSON to Codable https://app.quicktype.io/

Upvotes: 2

ChooGoo
ChooGoo

Reputation: 105

You can do it by following as far as I remember 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)
        }
    }

But really, as like Frankenstein said, the best way to solve your problem is just to conform your models to Codable.

Upvotes: 1

Related Questions