2017-01-13 1 views
2

ここでは、過去30日間のINRの通貨値を取得しようとしています。swift 3.0の非同期via URLを使用して複数のJSONデータを取得する方法

Alamofireを使用してINR通貨の過去30日間の値を取得しています。

//strDates contains all 30 days dates 

for i in 0..<strDates.count { 
    Alamofire.request("http://api.fixer.io/\(strDates[i])?base=USD").responseJSON { response in    
     if let arr = response.result.value as? [String:AnyObject] 
     { 
      let inrc = (arr["rates"]?["INR"] as? Double)! 
      print(inrc) 
      self.sValues.append(inc) 
      print(sValues) 
      //It prints values here. 
     } 
    } 
} 
print(sValues) //Print nil 

setChart(dataPoints: strDates, values: sValues) 

このsValues配列は、Alamofireブロックの外でどのように使用しますか。

ここでは、実際には、&のINR値を以下の方法のパラメータとして送信しています。

func setChart(dataPoints: [String], values: [Double]) { 
     barChartView.noDataText = "You need to provide data for the chart." 

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

     let chartDataSet = BarChartDataSet(values: dataEntries, label: "INR Rates(₹)/$") 
     let chartData = BarChartData(dataSet: chartDataSet) 
     barChartView.data = chartData 
     barChartView.xAxis.labelPosition = .bottom 
     barChartView.rightAxis.enabled = false 
     barChartView.leftAxis.enabled = true 
     barChartView.data?.setDrawValues(false) 
     barChartView.leftAxis.granularityEnabled = true 
     barChartView.leftAxis.granularity = 1.0 
     barChartView.xAxis.granularityEnabled = true 
     barChartView.xAxis.granularity = 1.0 
     barChartView.leftAxis.axisMinimum = 70//65 
     barChartView.leftAxis.axisMaximum = 60//70 

     //chartDataSet.colors = [UIColor.cyan, UIColor.green] 
    } 

答えて

1

すべてのコールが完了したときにチャートをリフレッシュすることをお探しですか?ですから、このようなパターンを使用する場合:多くのAPIリクエストが戻ってくると、すべての要求が行われたときにのみ行動を取る方法をカウントする

var completedCalls = 0 
    for i in 0..<strDates.count { 
     Alamofire.request("http://api.fixer.io/\(strDates[i])?base=USD").responseJSON { response in 
      if let arr = response.result.value as? [String:AnyObject] 
      { 
       completedCalls += 1 
       let inrc = (arr["rates"]?["INR"] as? Double)! 
       print(inrc) 
       self.sValues.append(inc) 
       print(sValues) 
       //It prints values here. 
       if completedCalls = strDates.count { 
        DispatchQueue.main { 
         setChart(dataPoints: strDates, values: sValues) 
        } 
       } 
      } 
     } 
    } 

アイデアはあるが(あなたがそれらのすべてが実際にも成功したことを確認する必要があります失敗した場合はエラーを表示します)。

+0

ありがとうございました。うまく動作します –

+0

こんにちは@Josh、新しい問題に直面しています。私が別のビューに移動してChartViewに戻ると、棒グラフが更新され、異なる値が表示されます。 –

+0

棒グラフを更新し、ナビゲートまたは更新するたびに毎回異なる値を表示します。 –

0

あなたのコードは、あなたのprint(sValues)リクエストの応答の前に走ったのでsValuesがnilを印刷する原因となります。このブロック

if let arr = response.result.value as? [String:AnyObject] 
{ 
    let inrc = (arr["rates"]?["INR"] as? Double)! 
    print(inrc) 
    self.sValues.append(inc) 
    print(sValues) 
    //It prints values here. 
} 

リクエストが値またはエラーとともに返された場合にのみ実行されます。したがって、あなたの要求からの価値の使用もここで行うべきです。この値を使用して特定のUI要素またはデータベースを更新する場合は、このブロック内のメソッドも呼び出す必要があります。

私は、非同期コードをプログラミングするときにこの考え方を採用することをお勧めします。これは、別のスレッドまたはサーバーで実行されているコードが復帰する際に期待できないものです。非同期コードが完了したときにのみ実行されるコンプリートブロックで戻り値を必要とするメソッドを実行する方が安全です。

0

テーブルに表示する場合は、Array型などの強力な変数や他のデータプロバイダ(CoreData、SQLiteなど)を作成し、そこに結果を格納します。 AFの完了ブロックで、Array変数の値をAPI結果データに設定(またはローカルデータプロバイダを更新)し、テーブル上でreloadData()を呼び出します。また、UITableViewデリゲートメソッドとデータソースメソッドをコンフィグレーションする必要があります。

+0

いいえこの配列をパラメータとして棒グラフに渡したいとします。 –

+0

グラフ形式で表示するには –

+0

次に、AF要求の完了ブロックに棒グラフを再描画する必要があります。 – brandonscript

関連する問題