Используйте данные на JSON с ячейками - PullRequest
0 голосов
/ 08 июня 2019

Я получил этот JSON из API:

{
    "oldest": "2019-01-24T00:00:00+00:00",
    "activities": [
        {
            "message": "<strong>Henrik</strong> didn't resist a guilty pleasure at <strong>Starbucks</strong>.",
            "amount": 2.5,
            "userId": 2,
            "timestamp": "2019-05-23T00:00:00+00:00"
        },
        {
            "message": "<strong>You</strong> made a manual transfer.",
            "amount": 10,
            "userId": 1,
            "timestamp": "2019-01-24T00:00:00+00:00"
        }
    ]
}

В нем есть много других действий.Как я могу получить к нему доступ и заполнить свои ячейки данными?Пока у меня есть этот код:

MainViewController:

struct Activities: Decodable {
    var oldest: String
    var activities: [Activity]
}

struct Activity: Decodable {
    var message: String
    var amount: Float
    var userId: Int
    var timestamp: String
}

class MainTableViewController: UITableViewController, UITableViewDataSourcePrefetching {

    var activityList: [Activities] = []
    var activity: [Activity] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.prefetchDataSource = self

        let activitiesJSONURLString = "https://qapital-ios-testtask.herokuapp.com/activities?from=2016-05-23T00:00:00+00:00&to=2019-05-23T00:00:00+00:00"
        guard let activitiesURL = URL(string: activitiesJSONURLString) else { return }

        URLSession.shared.dataTask(with: activitiesURL) { (data, response, err) in
            // perhaps check err
            // also perhaps check response status 200 OK

            guard let data = data else { return }

            do {
                // Activities
                let activities = try JSONDecoder().decode(Activities.self, from: data)

            } catch let jsonErr {
                print("Error serializing json: ", jsonErr)
            }

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

    // MARK: - Table view data source

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ActivityCell", for: indexPath) as! MainTableViewCell

        return cell
    }

    // Prefetching
    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
//        if indexPaths.contains(where: isLoadingCell) {
//            viewModel.fetchModerators()
//        }
    }
}

Но я думаю, что-то не так.Или я понятия не имею, с чего начать.Я мог бы действительно использовать некоторую помощь или любые советы, которые вы можете дать мне.Пожалуйста и спасибо!

Ответы [ 2 ]

0 голосов
/ 08 июня 2019

Во-первых, наименование структур довольно запутанно. Назовите корневой объект чем-то не связанным, например Response или Root.

И мы собираемся декодировать метки времени как Date

struct Root: Decodable {
    var oldest: Date
    var activities: [Activity]
}

struct Activity: Decodable {
    var message: String
    var amount: Float
    var userId: Int
    var timestamp: Date
}

Во-вторых, поскольку данные получены при всем соответствии с UITableViewDataSourcePrefetching, это бессмысленно. Удалите его и удалите также метод prefetchRowsAt.

Объявите только один массив источника данных и назовите его activities

var activities = [Activity]()

и удалить

var activityList: Activities!  

В обработчике завершения задачи данных декодируйте Root и присвойте массив действий массиву источника данных

 do {
    // Activities
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    let result = try decoder.decode(Root.self, from: data)
    self.activities = result.activities

    DispatchQueue.main.async {
       self.tableView.reloadData()
    }
 } catch {
    print("Error serializing json: ", error)
 }

Методы источника данных табличного представления:

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

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ActivityCell", for: indexPath) as! MainTableViewCell
    let activity = activities[indexPath.row]
    // assign the activity data to the UI for example
    // cell.someLabel = activity.amount
    return cell
}
0 голосов
/ 08 июня 2019

Поскольку вы используете activityList для определения количества строк, я предполагаю, что вы хотите использовать данные из activityList для заполнения ваших ActivityCell s. То есть, если вы не хотели, чтобы ActivityList был единственным экземпляром Activities вместо массива Activities, в этом случае вы, скорее всего, будете использовать activityList.activities.count для определения количества строк. В любом случае, давайте просто вызовем массив данных, который вы хотите использовать, чтобы заполнить ячейки activityList.

В этом случае вам следует обязательно обновить activityList до действий, которые вы извлекли из API. Если у вас есть activityList, вы можете использовать reloadData, который вызовет методы делегирования табличного представления. В tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) вы можете затем использовать activityList для обновления устаревшей ячейки.

Нечто подобное может быть тем, что вы хотите:

class MainTableViewController: UITableViewController, UITableViewDataSourcePrefetching {

    var activityList: Activities!
    var activity: [Activity] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.prefetchDataSource = self

        let activitiesJSONURLString = "https://qapital-ios-testtask.herokuapp.com/activities?from=2016-05-23T00:00:00+00:00&to=2019-05-23T00:00:00+00:00"
        guard let activitiesURL = URL(string: activitiesJSONURLString) else { return }

        URLSession.shared.dataTask(with: activitiesURL) { (data, response, err) in
            // perhaps check err
            // also perhaps check response status 200 OK

            guard let data = data else { return }

            do {
                // Activities
                let activities = try JSONDecoder().decode(Activities.self, from: data)
                self.activityList = activities

                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            } catch let jsonErr {
                print("Error serializing json: ", jsonErr)
            }

        }.resume()
    }

    // MARK: - Table view data source

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ActivityCell", for: indexPath) as! MainTableViewCell
        if let activity = activityList?[indexPath.row] {
            // UPDATE CELL ACCORDING TO activity
         }
        return cell
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...