Search code examples
iosswiftchartsios-charts

iOS chart showing before data has been retrieved from API - swift


I am trying to create my first live chart using iOS Charts and pulling in data from my database.

The data from my database consist of games won, drawn, lost. These are Integers (However iOS Charts is requiring that they be Doubles but this is another problem).

My main issue is the chart is not updating with my data - it works if I manually enter data in the line i.e let games = [4.0, 8.0, 2.0]. But with pulling in data from the database I get nothing.

import UIKit
import Charts

class ShowCommunityViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

//********CHART VARIABLES**************//

var totalWins: Double = 0.0
var totalDraws: Double = 0.0
var totalLosses: Double = 0.0

//**************************************

override func viewDidLoad() {

    results =  ["Won", "Drawn", "Lost"]
    let games = [totalWins, totalDraws, totalLosses]
    setChart(dataPoints: results, values: games)

}

// ******* CHARTS FUNCTIONS ************

func setChart(dataPoints: [String], values: [Double]){

    barChartView.noDataText = "you need to provide some data for the chart."

    var dataEntries: [BarChartDataEntry] = Array()

    for i in 0..<dataPoints.count {
        let dataEntry = BarChartDataEntry(x: Double(i), y: values[i])
        dataEntries.append(dataEntry)
    }

    let chartDataSet = BarChartDataSet(values: dataEntries, label: "Games Played")

    let chartData = BarChartData()
    self.barChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
    barChartView.leftAxis.granularityEnabled = true
    barChartView.rightAxis.enabled = false
    barChartView.leftAxis.granularity = 1.0
    chartData.addDataSet(chartDataSet)
    barChartView.data = chartData

}

// ********* API CALL *****

 override func viewDidAppear(_ animated: Bool) {

    let defaults = UserDefaults.standard
    let playerId = defaults.string(forKey: "playerId")
    let email = defaults.string(forKey: "userEmail")

    self.personalSelf = true

    let myUrl = URL(string: "http://www.xxx.uk/xxx/xxx.php?");
    var request = URLRequest(url:myUrl!);
    request.httpMethod = "POST";

    let postString = "community_id=\(comIds[communityId!])&player_id=\(playerId!)&email=\(email!)";

    request.httpBody = postString.data(using: String.Encoding.utf8);

    let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in

        DispatchQueue.main.async
            {

                if error != nil {
                    print("error=\(error)")
                    return
                }

                do{
                    let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject]
                    print (json!)

                if let dict = json?["Stats"] as? [String:AnyObject] {
                    if  let total_Wins = dict["totalWins"] as? Double,
                        let total_Draws = dict["totalDraws"] as? Double,
                        let total_Losses = dict ["totalLosses"] as? Double{
                    self.totalWins = total_Wins
                    self.totalDraws = total_Draws
                    self.totalLosses = total_Losses
                    }


                } catch{
                    print(error)
                }
        }
        }
    task.resume()


}

My problem is that the chart is not updating. I am guessing this is because the chart is being displayed before the data has been fetched?

....On a side note, I would prefer to show Int and not Floats but it is requiring everything be a double

Where am I going wrong?

UPDATE:

Solution working- is showing floats rather than Ints and missing label from bottom of graph, is showing numbers instead of "Won", "Drawn", "Lost"

enter image description here


Solution

  • self.totalWins = total_Wins
     self.totalDraws = total_Draws
     self.totalLosses = total_Losses
    

    // add this lines in your response

    results =  ["Won", "Drawn", "Lost"]
    let games = [total_Wins, total_Draws, total_Losses]
    setChart(dataPoints: results, values: games)
    

    Check output.