在表格视图中显示JSON数据

时间:2018-12-14 19:19:31

标签: json swift

我不知道为什么无法在表视图上显示JSON数据。我试图获取JSON数据,但无法以表格格式在屏幕上显示它。

import UIKit

class User{
    var userId : Int
    var id : Int
    var title : String
    var completed : Bool

    init (userId : Int , id: Int, title : String, completed : Bool){
        self.userId = userId
        self.id = id
        self.title = title
        self.completed = completed
    }
}



class ViewController: UITableViewController{

    var users = [User]()

    let cellId = "cellId"

    override func viewDidLoad() {
        super.viewDidLoad()
        makeGetCall()

        //makePostCall()
}


    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return users.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
        let user = users[indexPath.row]
        cell.textLabel?.text = user.title
        cell.detailTextLabel?.text = user.title
        return cell
    }

    func makeGetCall(){

       // users = []

        let todoEndpoint: String = "http://jsonplaceholder.typicode.com/todos"
        guard let url = URL(string: todoEndpoint) else {
            print("Error: cannot create URL")
            return
        }
        let urlRequest = URLRequest(url: url)

        // set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

        // make the request
        let task = session.dataTask(with: urlRequest) {
            (data, response, error) in
            // check for any errors
            guard error == nil else {
                print("error calling GET on /todos/1")
                print(error!)
                return
            }
            // make sure we got data
            guard let responseData = data else {
                print("Error: did not receive data")
                return
            }
            // parse the result as JSON, since that's what the API provides
            do {
                let todo = try JSONSerialization.jsonObject(with: responseData, options: .mutableLeaves)
                    as? NSArray

                for eachUser in todo! {
                    let eachUsers = eachUser as! [String : AnyObject]
                    let userId = eachUsers["userId"] as! Int
                    let id = eachUsers["id"] as! Int
                    let title = eachUsers["title"] as! String
                    let completed = eachUsers["completed"] as! Bool

                    self.users.append(User(userId: userId, id: id, title: title, completed: completed))
                    print(eachUser)

                    DispatchQueue.main.async {
                        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: self.cellId)
                    }

                }

            } catch  {
                print("error trying to convert data to JSON")
                return
            }
        }
        task.resume()
}


    func makePostCall() {
        let todosEndpoint: String = "https://jsonplaceholder.typicode.com/todos"
        guard let todosURL = URL(string: todosEndpoint) else {
            print("Error: cannot create URL")
            return
        }
        var todosUrlRequest = URLRequest(url: todosURL)
        todosUrlRequest.httpMethod = "POST"
        let newTodo: [String: Any] = ["title": "First todo", "completed": false, "userId": 1]
        let jsonTodo: Data
        do {
            jsonTodo = try JSONSerialization.data(withJSONObject: newTodo, options: [])
            todosUrlRequest.httpBody = jsonTodo
        } catch {
            print("Error: cannot create JSON from todo")
            return
        }

        let session = URLSession.shared

        let task = session.dataTask(with: todosUrlRequest) {
            (data, response, error) in
            guard error == nil else {
                print("error calling POST on /todos/1")
                print(error!)
                return
            }
            guard let responseData = data else {
                print("Error: did not receive data")
                return
            }

            // parse the result as JSON, since that's what the API provides
            do {
                guard let receivedTodo = try JSONSerialization.jsonObject(with: responseData,options: []) as? [String: Any] else {
                    print("Could not get JSON from responseData as dictionary")
                    return
                }
                print("The todo is: " + receivedTodo.description)

                guard let todoID = receivedTodo["id"] as? Int else {
                    print("Could not get todoID as int from JSON")
                    return
                }


                print("The ID is: \(todoID)")
            } catch  {
                print("error parsing response from POST on /todos")
                return
            }
        }
        task.resume()
    }

}

1 个答案:

答案 0 :(得分:1)

您需要在添加数据后重新加载表

DispatchQueue.main.async {
   self.tableView.reloadData()
}

注册行应位于viewDidLoad

self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: self.cellId)

一种好方法就是使用

struct User :Decodable{ 
  let userId , id : Int 
  let title : String 
  let completed : Bool
}

users = try? JSONDecoder().decode([User].self,from:data)