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