2016-07-26 35 views
-1

我试图将JSON雅虎API中的某些数据放入一些UILabels中。 当我尝试运行我的项目时,我遇到了线程1错误。如何将JSON数据放入使用AlamoFire和Swift的UILabel中

下面是我的一些代码:

@IBOutlet weak var tableView: UITableView! 
var stockSymbol: String = "AAPL" 
var stock: [Stock] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 
    tableView.dataSource = self 
    tableView.delegate = self 
    tableView.registerNib(UINib(nibName: "HomeCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: "homeCell") 
    tableView.rowHeight = 60 

    // Do any additional setup after loading the view. 
    SwiftStockKit.fetchStockForSymbol(symbol: stockSymbol) { (stock) ->() in 
    self.stock = [stock] 
     self.tableView.reloadData() 


    } 
} 

class func fetchStockForSymbol(symbol symbol: String, completion:(stock: Stock) ->()) { 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 

     let stockURL = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22AAPL%22)&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&format=json" 

     Alamofire.request(.GET, stockURL).responseJSON { response in 

      if let resultJSON = response.result.value as? [String : AnyObject] { 

       if let stockData = ((resultJSON["query"] as! [String : AnyObject])["results"] as! [String : AnyObject])["quote"] as? [String : AnyObject] { 

        // lengthy creation, yeah 
        var dataFields = [[String : String]]() 
        dataFields.append(["Ask" : stockData["Ask"] as? String ?? "N/A"]) 
        dataFields.append(["Average Daily Volume" : stockData["AverageDailyVolume"] as? String ?? "N/A"]) 
        dataFields.append(["Bid" : stockData["Bid"] as? String ?? "N/A"]) 
        dataFields.append(["Book Value" : stockData["BookValue"] as? String ?? "N/A"]) 
        dataFields.append(["Change" : stockData["Change"] as? String ?? "N/A"]) 
        dataFields.append(["Percent Change" : stockData["ChangeinPercent"] as? String ?? "N/A"]) 
        dataFields.append(["Day High" : stockData["DaysHigh"] as? String ?? "N/A"]) 
        dataFields.append(["Day Low" : stockData["DaysLow"] as? String ?? "N/A"]) 
        dataFields.append(["Div/Share" : stockData["DividendShare"] as? String ?? "N/A"]) 
        dataFields.append(["Div Yield" : stockData["DividendYield"] as? String ?? "N/A"]) 
        dataFields.append(["EBITDA" : stockData["EBITDA"] as? String ?? "N/A"]) 
        dataFields.append(["Current Yr EPS Estimate" : stockData["EPSEstimateCurrentYear"] as? String ?? "N/A"]) 
        dataFields.append(["Next Qtr EPS Estimate" : stockData["EPSEstimateNextQuarter"] as? String ?? "N/A"]) 
        dataFields.append(["Next Yr EPS Estimate" : stockData["EPSEstimateNextYear"] as? String ?? "N/A"]) 
        dataFields.append(["Earnings/Share" : stockData["EarningsShare"] as? String ?? "N/A"]) 
        dataFields.append(["50D MA" : stockData["FiftydayMovingAverage"] as? String ?? "N/A"]) 
        dataFields.append(["Last Trade Date" : stockData["LastTradeDate"] as? String ?? "N/A"]) 
        dataFields.append(["Last" : stockData["LastTradePriceOnly"] as? String ?? "N/A"]) 
        dataFields.append(["Last Trade Time" : stockData["LastTradeTime"] as? String ?? "N/A"]) 
        dataFields.append(["Market Cap" : stockData["MarketCapitalization"] as? String ?? "N/A"]) 
        dataFields.append(["Company" : stockData["Name"] as? String ?? "N/A"]) 
        dataFields.append(["One Yr Target" : stockData["OneyrTargetPrice"] as? String ?? "N/A"]) 
        dataFields.append(["Open" : stockData["Open"] as? String ?? "N/A"]) 
        dataFields.append(["PEG Ratio" : stockData["PEGRatio"] as? String ?? "N/A"]) 
        dataFields.append(["PE Ratio" : stockData["PERatio"] as? String ?? "N/A"]) 
        dataFields.append(["Previous Close" : stockData["PreviousClose"] as? String ?? "N/A"]) 
        dataFields.append(["Price-Book" : stockData["PriceBook"] as? String ?? "N/A"]) 
        dataFields.append(["Price-Sales" : stockData["PriceSales"] as? String ?? "N/A"]) 
        dataFields.append(["Short Ratio" : stockData["ShortRatio"] as? String ?? "N/A"]) 
        dataFields.append(["Stock Exchange" : stockData["StockExchange"] as? String ?? "N/A"]) 
        dataFields.append(["Symbol" : stockData["Symbol"] as? String ?? "N/A"]) 
        dataFields.append(["200D MA" : stockData["TwoHundreddayMovingAverage"] as? String ?? "N/A"]) 
        dataFields.append(["Volume" : stockData["Volume"] as? String ?? "N/A"]) 
        dataFields.append(["52w High" : stockData["YearHigh"] as? String ?? "N/A"]) 
        dataFields.append(["52w Low" : stockData["YearLow"] as? String ?? "N/A"]) 



        let stock = Stock(

         ask: dataFields[0].values.first, 
         averageDailyVolume: dataFields[1].values.first, 
         bid: dataFields[2].values.first, 
         bookValue: dataFields[3].values.first, 
         changeNumeric: dataFields[4].values.first, 
         changePercent: dataFields[5].values.first, 
         dayHigh: dataFields[6].values.first, 
         dayLow: dataFields[7].values.first, 
         dividendShare: dataFields[8].values.first, 
         dividendYield: dataFields[9].values.first, 
         ebitda: dataFields[10].values.first, 
         epsEstimateCurrentYear: dataFields[11].values.first, 
         epsEstimateNextQtr: dataFields[12].values.first, 
         epsEstimateNextYr: dataFields[13].values.first, 
         eps: dataFields[14].values.first, 
         fiftydayMovingAverage: dataFields[15].values.first, 
         lastTradeDate: dataFields[16].values.first, 
         last: dataFields[17].values.first, 
         lastTradeTime: dataFields[18].values.first, 
         marketCap: dataFields[19].values.first, 
         companyName: dataFields[20].values.first, 
         oneYearTarget: dataFields[21].values.first, 
         open: dataFields[22].values.first, 
         pegRatio: dataFields[23].values.first, 
         peRatio: dataFields[24].values.first, 
         previousClose: dataFields[25].values.first, 
         priceBook: dataFields[26].values.first, 
         priceSales: dataFields[27].values.first, 
         shortRatio: dataFields[28].values.first, 
         stockExchange: dataFields[29].values.first, 
         symbol: dataFields[30].values.first, 
         twoHundreddayMovingAverage: dataFields[31].values.first, 
         volume: dataFields[32].values.first, 
         yearHigh: dataFields[33].values.first, 
         yearLow: dataFields[34].values.first, 
         dataFields: dataFields 


        ) 
        dispatch_async(dispatch_get_main_queue()) { 
         completion(stock: stock) 
        } 
       } 
      } 
     } 
    } 
} 

这是结构:

struct Stock { 

    var ask: String? 
    var averageDailyVolume: String? 
    var bid: String? 
    var bookValue: String? 
    var changeNumeric: String? 
    var changePercent: String? 
    var dayHigh: String? 
    var dayLow: String? 
    var dividendShare: String? 
    var dividendYield: String? 
    var ebitda: String? 
    var epsEstimateCurrentYear: String? 
    var epsEstimateNextQtr: String? 
    var epsEstimateNextYr: String? 
    var eps: String? 
    var fiftydayMovingAverage: String? 
    var lastTradeDate: String? 
    var last: String? 
    var lastTradeTime: String? 
    var marketCap: String? 
    var companyName: String? 
    var oneYearTarget: String? 
    var open: String? 
    var pegRatio: String? 
    var peRatio: String? 
    var previousClose: String? 
    var priceBook: String? 
    var priceSales: String? 
    var shortRatio: String? 
    var stockExchange: String? 
    var symbol: String? 
    var twoHundreddayMovingAverage: String? 
    var volume: String? 
    var yearHigh: String? 
    var yearLow: String? 

    var dataFields: [[String : String]] 

}

,我也有可能与显示数据的能力妨碍不同stockurl我swiftStockKit文件到UILabel

 
let stockURL = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22AAPL%22)&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&format=json" 

其余的都是一样的。

回答

0

几点建议:

  • 雅虎提供https所以使用
  • 你不需要Alamofire请求之前调用dispatch_async。该请求将默认在后台线程上执行。
  • 由于您正在映射一长串字段,最好使用像ObjectMapper这样的JSON到对象映射框架。您可以使用其原生数据类型而不是字符串。
  • 我不能帮助“线程1错误”,因为我没有看到您的tableView:cellForRowAtIndexPath:方法。所以这个答案的其余部分将重点放在JSON处理

您需要稍微重新定义Stock结构(编辑为简洁起见):

import Foundation 
import ObjectMapper 

struct Stock: Mappable { 
    var symbol: String? 
    var ask: Double? 
    var lastTradeDate: NSDate? 
    // other fields... 

    var dataFields = [[String : String]]() 

    init?(_ map: Map) { 
     // Perform validation of the JSON here 
     // Leave blank if you don't need to validate anything 
    } 

    mutating func mapping(map: Map) { 
     symbol   <- map["query.results.quote.symbol"] // maps to a String 
     ask    <- map["query.results.quote.Ask"] // maps to a Double 

     // You probably want to combine this with LastTradeTime 
     // but I'm keeing them as separate for now 
     lastTradeDate <- (map["query.results.quote.LastTradeDate"], MyDateTransform()) 
    } 
} 

// We need a custom date formatter since Yahoo doesn't 
// return the standard format of yyyy-MM-dd 
class MyDateTransform : TransformType { 
    typealias Object = NSDate 
    typealias JSON = String 

    static let dateFormatter = { Void -> NSDateFormatter in 
     let formatter = NSDateFormatter() 
     formatter.dateFormat = "M/d/yyyy" 

     return formatter 
    }() 

    func transformFromJSON(value: AnyObject?) -> NSDate? { 
     if let stringValue = value as? String { 
      return MyDateTransform.dateFormatter.dateFromString(stringValue) 
     } else { 
      return nil 
     } 
    } 

    func transformToJSON(value: NSDate?) -> String? { 
     if let dateValue = value { 
      return MyDateTransform.dateFormatter.stringFromDate(dateValue) 
     } else { 
      return nil 
     } 
    } 
} 

用法:

let stockURL = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22AAPL%22)&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&format=json" 

Alamofire.request(.POST, stockURL) 
    .validate() 
    .responseJSON { response in 
     guard response.result.isSuccess else { 
      print(response.result.error!) 
      return 
     } 

     // This is all it takes to initiate a new object from JSON 
     let stock = Mapper<Stock>().map(response.result.value) 
    } 
+0

谢谢为了您的回应,我只是有一个简单的问题。我基本上使用了Stock结构代码,但添加了 class func fetchPennyStockForBidAndFilter(symbol symbol:String,bid:String,completion:(filteredstock:filteredStock) - >())dispatch_async(dispatch_get_global_queue首先,我想知道我是否做到了这一点,其次,我会如何将来自url的信息放入uilabel。谢谢。 –

+0

我不明白为什么在完成处理程序中调用'dispatch_async'到后台队列。如果你想设置'UILabel'的文本,调用它到主队列。你想在'UILabel'上显示哪些信息?例如,要显示要价,你可以设置'label.text =“\(filteredStock.ask)”'(尽管最好使用'NSNumberFormatter') –

+0

好的非常感谢你,你不必回应,但我打算展示符号和投标。 –

相关问题