2017-01-11 64 views
0

我有一個從YQL(使用Alamofire)獲取當前股票價格的函數顯示出來:不正確的股票價格從YQL請求(SWIFT)

func stockFetcher(completion: @escaping ([String]?) -> Void) { 
Alamofire.request(stockUrl).responseJSON { (responseData) -> Void in 
    if((responseData.result.value) != nil) { 
     let json = JSON(responseData.result.value!) 
     if let appleStockPrice = json["query"]["results"]["quote"][0]["Ask"].string { 
      prices.append(appleStockPrice) 
     } 
     if let googleStockPrice = json["query"]["results"]["quote"][1]["Ask"].string { 
      prices.append(googleStockPrice) 
     } 
     if let twitterStockPrice = json["query"]["results"]["quote"][2]["Ask"].string { 
      prices.append(twitterStockPrice) 
     } 
     if let teslaStockPrice = json["query"]["results"]["quote"][3]["Ask"].string { 
      prices.append(teslaStockPrice) 
     } 
     if let samsungStockPrice = json["query"]["results"]["quote"][4]["Ask"].string { 
      prices.append(samsungStockPrice) 
     } 
     completion(prices) 
     print(json) 
    } 
} 
} 

這裏所返回的JSON,一切看起來除了空爲好Twitter的,但是這是一個單獨的問題:

{ 
"query" : { 
"created" : "2017-01-11T16:34:51Z", 
"results" : { 
    "quote" : [ 
    { 
     "symbol" : "AAPL", 
     "YearLow" : "89.4700", 
     "YearHigh" : "119.3600", 
     "Ask" : "119.1100" 
    }, 
    { 
     "symbol" : "GOOG", 
     "YearLow" : "663.06", 
     "YearHigh" : "816.68", 
     "Ask" : "805.08" 
    }, 
    { 
     "symbol" : "TWTR", 
     "YearLow" : "13.730", 
     "YearHigh" : "25.250", 
     "Ask" : null 
    }, 
    { 
     "symbol" : "TSLA", 
     "YearLow" : "141.0500", 
     "YearHigh" : "269.3400", 
     "Ask" : "227.8600" 
    }, 
    { 
     "symbol" : "SSNLF", 
     "YearLow" : "1000.00", 
     "YearHigh" : "1600.00", 
     "Ask" : null 
    } 
    ] 
}, 
"count" : 5, 
"lang" : "en;q=1.0" 
    } 
} 

在我的tableview我(在cellForRow)顯示價格像這樣:

stockFetcher(completion: { 
     (prices) -> Void in 

     if (prices?.count)! > indexPath.row + 1 { 
      cell.detailTextLabel?.text = "Current Stock Price: \(prices![indexPath.row])" 
     } else { 
      cell.detailTextLabel?.text = "No data found" 
     } 
    }) 

前三款顯示的是正確的價格,但是特斯拉顯示了蘋果目前的價格(在這種情況下爲119),而三星顯示的是谷歌的價格(在這種情況下爲804) - 看起來像前三種價格剛開始重複。

任何人都可以看到問題在哪裏?

編輯:cellForRow

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CompanyCell 

    // Labels 
    cell.textLabel?.text = companyNames[indexPath.row] 

    // Detail labels 
    stockFetcher(completion: { 
     (prices) -> Void in 

     if (prices?.count)! > indexPath.row + 1 { 
      cell.detailTextLabel?.text = "Current Stock Price: \(prices![indexPath.row])" 
     } else { 
      cell.detailTextLabel?.text = "No data found" 
     } 
    }) 

    return cell 
} 
+0

這不起作用。 UITableView重用了單元,所以你需要使用UITableViewDataSource中的委託方法。你可以在這裏閱讀如何使用UITableView:https://developer.apple.com/reference/uikit/uitableview – dlbuckley

+0

你能擴展你的答案嗎?我知道UITableView的委託方法並正在使用它們。 – d0xi45

+1

您可以將cellForRowAtIndexPath方法的代碼添加到問題中嗎?它會給你的代碼更多的上下文,謝謝! – dlbuckley

回答

0

stockFetcher做某些異步(與完成塊的網絡請求),而在完成塊保留於可再使用的單元格的參考。當Alamofire返回數據時,該單元格可能正在其他地方使用。你不應該堅持單元格引用並做一些異步操作。相反,您應該異步獲取表格視圖數據源方法以外的數據,然後在觸發cellForRowAt時,只需從存儲的數據中讀取數據即可。

+0

謝謝!我會給它一個鏡頭。如果我理解正確(仍在學習繩索),您建議將stockFetcher完成塊移出cellForRow,然後從該數據設置detailTextLabels? – d0xi45

+0

獲取外部數據 - 然後在tableDataSource中的某處設置價格,然後在tableView上調用reloadData以觸發重新填充此數組中 – muescha

+0

的表格,並使用當前代碼重新爲每個表格單元調用stockfetcher(並且還會在您滾動時表格和單元格被重新繪製),您應該避免這種情況,並且只在表格外調用它一次(同時爲了避免被禁止調用太多時間的api)。你也應該將結果緩存爲api友好的,並避免多次調用api – muescha