Swift 使用Yahoo Finance API和Alamofire获取股票价格,然后将其绘制在图表上

Swift 使用Yahoo Finance API和Alamofire获取股票价格,然后将其绘制在图表上,swift,graph,alamofire,yahoo-finance,Swift,Graph,Alamofire,Yahoo Finance,我试图从雅虎财经API获取股票价格,然后将其绘制在图表上。我有一个从雅虎获取股票价格的函数,但是我需要转换它们,这样它就可以被一个图表使用。我使用SwiftChart Cocoapod来绘制图形,在他们使用pod的示例中,他们有一个部分,从.json文件中获取苹果股票的价格,然后将其解析到图形中。我需要将Yahoo数据转换为相同的格式,以便将其放入图形中 这是获取雅虎金融股票的代码: //获取股票图表点数 func fetchChartPoints(symbol: String, range:

我试图从雅虎财经API获取股票价格,然后将其绘制在图表上。我有一个从雅虎获取股票价格的函数,但是我需要转换它们,这样它就可以被一个图表使用。我使用SwiftChart Cocoapod来绘制图形,在他们使用pod的示例中,他们有一个部分,从.json文件中获取苹果股票的价格,然后将其解析到图形中。我需要将Yahoo数据转换为相同的格式,以便将其放入图形中

这是获取雅虎金融股票的代码:

//获取股票图表点数

func fetchChartPoints(symbol: String, range: ChartTimeRange, completion:@escaping (_ chartPoints: [ChartPoint]) -> ()) {

    DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {

        //An Alamofire regular responseJSON wont parse the JSONP with a callback wrapper correctly, so lets work around that.
        let chartURL = SwiftStockGraphKit.chartUrlForRange(symbol, range: range)

        Alamofire.request(chartURL, method: .get).responseData { response in

            if let data = response.result.value {

                var jsonString =  NSString(data: data, encoding: String.Encoding.utf8.rawValue)!

                jsonString = jsonString.substring(from: 30) as NSString
                jsonString = jsonString.substring(to: jsonString.length-1) as NSString

                if let data = jsonString.data(using: String.Encoding.utf8.rawValue) {
                    if let resultJSON = (try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions(rawValue: 0)))  as? [String : AnyObject] {

                        let series = resultJSON["series"] as! [[String : AnyObject]]
                        var chartPoints = [ChartPoint]()
                        for dataPoint in series {
                            //GMT off by 5 hrs
                            let date = NSDate(timeIntervalSince1970: (dataPoint["Timestamp"] as? Double ?? dataPoint["Date"] as! Double) - 18000.0)

                            chartPoints.append(
                                ChartPoint(
                                    date:  date as Date,
                                    volume: dataPoint["volume"] as? Int,
                                    open: dataPoint["open"] as? CGFloat,
                                    close: dataPoint["close"] as? CGFloat,
                                    low: dataPoint["low"] as? CGFloat,
                                    high: dataPoint["high"] as? CGFloat
                                )
                            )
                        }
                        DispatchQueue.main.async() {
                            completion(chartPoints)
                        }
                    }
                }
            }
        }
    }
}

//
// Graph Time Frame
//

class func chartUrlForRange(_ symbol: String, range: ChartTimeRange) -> String {

    var timeString = String()

    switch (range) {
    case .oneDay:
        timeString = "1d"
    case .fiveDays:
        timeString = "5d"
    case .tenDays:
        timeString = "10d"
    case .oneMonth:
        timeString = "1m"
    case .threeMonths:
        timeString = "3m"
    case .oneYear:
        timeString = "1y"
    case .fiveYears:
        timeString = "5y"
    }

    return "http://chartapi.finance.yahoo.com/instrument/1.0/\(symbol)/chartdata;type=quote;range=\(timeString)/json"
}
这是SwiftCharts用来获取JSON文件并将其转换为图形的代码:

import UIKit
import SwiftChart

class StockChartViewController: UIViewController, ChartDelegate {

var selectedChart = 0

@IBOutlet weak var labelLeadingMarginConstraint: NSLayoutConstraint!
@IBOutlet weak var label: UILabel!
@IBOutlet weak var chart: Chart!

fileprivate var labelLeadingMarginInitialConstant: CGFloat!

override func viewDidLoad() {

    labelLeadingMarginInitialConstant = labelLeadingMarginConstraint.constant
    initializeChart()

}

func initializeChart() {
    chart.delegate = self

    // Initialize data series and labels
    let stockValues = getStockValues()

    var serieData: [Float] = []
    var labels: [Float] = []
    var labelsAsString: Array<String> = []

    // Date formatter to retrieve the month names
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MM"

    for (i, value) in stockValues.enumerated() {

        serieData.append(value["close"] as! Float)

        // Use only one label for each month
        let month = Int(dateFormatter.string(from: value["date"] as! Date))!
        let monthAsString:String = dateFormatter.monthSymbols[month - 1] 
        if (labels.count == 0 || labelsAsString.last != monthAsString) {
            labels.append(Float(i))
            labelsAsString.append(monthAsString)
        }
    }

    let series = ChartSeries(serieData)
    series.area = true

    // Configure chart layout

    chart.lineWidth = 0.5
    chart.labelFont = UIFont.systemFont(ofSize: 12)
    chart.xLabels = labels
    chart.xLabelsFormatter = { (labelIndex: Int, labelValue: Float) -> String in
        return labelsAsString[labelIndex]
    }
    chart.xLabelsTextAlignment = .center
    chart.yLabelsOnRightSide = true
    // Add some padding above the x-axis
    chart.minY = serieData.min()! - 5

    chart.add(series)

}
// Chart delegate

func didTouchChart(_ chart: Chart, indexes: Array<Int?>, x: Float, left: CGFloat) {

    if let value = chart.valueForSeries(0, atIndex: indexes[0]) {

        let numberFormatter = NumberFormatter()
        numberFormatter.minimumFractionDigits = 2
        numberFormatter.maximumFractionDigits = 2
        label.text = numberFormatter.string(from: NSNumber(value: value))

        // Align the label to the touch left position, centered
        var constant = labelLeadingMarginInitialConstant + left - (label.frame.width / 2)

        // Avoid placing the label on the left of the chart
        if constant < labelLeadingMarginInitialConstant {
            constant = labelLeadingMarginInitialConstant
        }

        // Avoid placing the label on the right of the chart
        let rightMargin = chart.frame.width - label.frame.width
        if constant > rightMargin {
            constant = rightMargin
        }

        labelLeadingMarginConstraint.constant = constant

    }

}

func didFinishTouchingChart(_ chart: Chart) {
    label.text = ""
    labelLeadingMarginConstraint.constant = labelLeadingMarginInitialConstant
}

func didEndTouchingChart(_ chart: Chart) {

}


func getStockValues() -> Array<Dictionary<String, Any>> {

    // Read the JSON file
    let filePath = Bundle.main.path(forResource: "AAPL", ofType: "json")!
    let jsonData = try? Data(contentsOf: URL(fileURLWithPath: filePath))
    let json: NSDictionary = (try! JSONSerialization.jsonObject(with: jsonData!, options: [])) as! NSDictionary
    let jsonValues = json["quotes"] as! Array<NSDictionary>

    // Parse data
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    let values = jsonValues.map { (value: NSDictionary) -> Dictionary<String, Any> in
        let date = dateFormatter.date(from: value["date"]! as! String)
        let close = (value["close"]! as! NSNumber).floatValue
        return ["date": date!, "close": close]
    }

    return values

}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

    super.viewWillTransition(to: size, with: coordinator)

    // Redraw chart on rotation
    chart.setNeedsDisplay()

}


}
导入UIKit
导入快捷图表
类StockChartViewController:UIViewController、ChartDelegate{
var selectedChart=0
@IBOutlet弱var labelLeadingMarginConstraint:NSLayoutConstraint!
@IBVAR标签:UILabel!
@IBVAR图表:图表!
fileprivate变量labelLeadingMarginInitialConstant:CGFloat!
重写func viewDidLoad(){
labelLeadingMarginInitialConstant=labelLeadingMarginConstraint.constant
草签
}
func initializeChart(){
chart.delegate=self
//初始化数据系列和标签
让stockValues=getStockValues()
变量serieData:[浮动]=[]
变量标签:[浮动]=[]
var labelasstring:Array=[]
//用于检索月份名称的日期格式化程序
让dateFormatter=dateFormatter()
dateFormatter.dateFormat=“MM”
对于stockValues.enumerated()中的(i,value){
serieData.append(值[“close”]as!Float)
//每个月只使用一个标签
让month=Int(dateFormatter.string(from:value[“date”]as!date))!
让monthastring:String=dateFormatter.monthSymbols[month-1]
if(labels.count==0 | | labelasstring.last!=monthastring){
标签.附加(浮动(i))
labelasstring.append(monthastring)
}
}
let系列=图表系列(serieData)
series.area=true
//配置图表布局
chart.lineWidth=0.5
chart.labelFont=UIFont.systemFont(大小:12)
chart.xLabels=标签
chart.xLabelsFormatter={(labelIndex:Int,labelValue:Float)->字符串输入
返回标签串[labelIndex]
}
chart.xLabelsTextAlignment=.center
chart.yLabelsOnRightSide=true
//在x轴上方添加一些填充
chart.minY=serieData.min()!-5
图表.添加(系列)
}
//图表代表
func didTouchChart(uChart:chart,index:Array,x:Float,left:CGFloat){
如果let value=chart.valueForSeries(0,atIndex:index[0]){
设numberFormatter=numberFormatter()
numberFormatter.minimumFractionDigits=2
numberFormatter.maximumFractionDigits=2
label.text=numberFormatter.string(from:NSNumber(value:value))
//将标签对准触摸左侧位置,居中
var常量=labelLeadingMarginInitialConstant+左-(label.frame.width/2)
//避免将标签放在图表的左侧
如果常数右边距{
常数=右边距
}
labelLeadingMarginConstraint.constant=常数
}
}
func didFinishTouchingChart(图表:图表){
label.text=“”
labelLeadingMarginConstraint.constant=labelLeadingMarginInitialConstant
}
func DiEndTouchingChart(uChart:chart){
}
func getStockValues()->数组{
//读取JSON文件
让filePath=Bundle.main.path(forResource:“AAPL”,类型为:“json”)!
让jsonData=try?数据(contentsOf:URL(fileURLWithPath:filePath))
让json:NSDictionary=(try!JSONSerialization.jsonObject(with:jsonData!,options:[])作为!NSDictionary
让jsonValues=json[“quotes”]作为!数组
//解析数据
让dateFormatter=dateFormatter()
dateFormatter.dateFormat=“yyyy-MM-dd”
让values=jsonValues.map{(值:NSDictionary)->中的Dictionary
let date=dateFormatter.date(from:value[“date”]!as!String)
让close=(值[“close”]!as!NSNumber)。floatValue
返回[“日期”:日期!,“关闭”:关闭]
}
返回值
}
重写func viewWillTransition(到大小:CGSize,带协调器:UIViewControllerTransitionCoordinator){
super.viewWillTransition(到:大小,带:协调器)
//重新绘制旋转图表
chart.setNeedsDisplay()
}
}

请帮忙,这样我就可以把股票价格直接放到一个图表中。

听起来你应该用雅虎的结果替换getStockValues函数中的jsonData!财经API。您可以发布一个指向apple json文件的链接吗?我已经尝试过这样做,但当您将json函数更改为获取Yahoo Finance图表点的fetchChartPoints函数,然后在func initializeChart()中将let stockValues=getStockValues()更改为let stockValues=fetchChartPoints时,会出现一些问题然后它会导致stockValues中的for(i,value)出现错误。enumerated(){saying value of type'(String,ChartTimeRange,@escaping([ChartPoint])->())->()'没有成员“enumerated”