簡體   English   中英

快速將實時數據更新到UITableview行

[英]Update Realtime data to UITableview row in swift

我有一個websocket服務器,該服務器根據我的訂閱每兩秒鍾推送一次數據。 我需要基於tableview中的更新行。目前,我正在使用Starscream模塊進行websocket實現。 如何將特定的行值更新為每兩秒

import UIKit
import Starscream
struct Stocks: Codable {
    let changepercent: String
    let changeprice: String
    let close: String
    let currentprice: String
    let high: String
    let id: Int
    let low: String
    let name: String
    let `open`: String
    let type: String
    let instid: String
    let exchange: String
}
class ViewController: UIViewController, WebSocketDelegate,UITableViewDelegate,UITableViewDataSource {
    @IBOutlet weak var stocktableView: UITableView!

    var arrContacts = [Stocks]()
    var socket: WebSocket!

    override func viewDidLoad() {
        super.viewDidLoad()
       var request = URLRequest(url: URL(string: "ws://192.168.18.97:8080/sss/landingstream")!)
            //var request = URLRequest(url: URL(string: "ws://192.168.18.97:8080/Setrega/landingstream")!)
        request.timeoutInterval = 5
        socket = WebSocket(request: request)

        socket.delegate = self
        socket.connect()
    }

    // MARK: Websocket Delegate Methods.

    func websocketDidConnect(socket: WebSocketClient) {

        print("websocket is connected")
    }

    func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
        if let e = error as? WSError {
            print("websocket is disconnected: \(e.message)")
        } else if let e = error {
            print("websocket is disconnected: \(e.localizedDescription)")
        } else {
             print("websocket disconnected")
        }
    }

    func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
        print("Received text: \(text)")
        let decoder = JSONDecoder()
        do {
            let iexEvent: Stocks = try decoder.decode(Stocks.self, from: text.data(using: .utf8)!)

            DispatchQueue.main.async {

                self.stocktableView.reloadData()

            }
        } catch {
            print(error)
        }
    }

    func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
        print("Received data: \(data.count)")
    }

    // MARK: Write Text Action

    @IBAction func writeText(_ sender: UIBarButtonItem) {
        socket.write(string: "{\"requestType\": \"INSTRUMENT_PRICE\",\"topic\": \"SBIN\"}")

    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.arrContacts.count;
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "StocksCell", for: indexPath)
        cell.textLabel?.text = arrContacts[indexPath.row].changeprice
        return cell
    }
    // MARK: Disconnect Action

    @IBAction func disconnect(_ sender: UIBarButtonItem) {
        if socket.isConnected {
            sender.title = "Connect"
            socket.disconnect()
        } else {
            sender.title = "Disconnect"
            socket.connect()
        }
    }

}

代替這個:

DispatchQueue.main.async {

    self.stocktableView.reloadData()
}

嘗試查找使用此功能更改的行:

final func indexesOfStocks(stocks:[Stocks]) -> [Int] {

    return stocks.reduce([]) { (currentResult, currentStocks) in

        if let currentStockIndex = self.arrContacts.index(where: { currentStocks.id == $0.id }) {

            return currentResult + [currentStockIndex]
        }
        return currentResult
    }
}

更新屬性arrContacts

final func updateArrContacts(indexesOfStocksValue:[Int], iexEvents:[Stocks]) {

    for i in stride(from: 0, to: indexesOfStocksValue.count, by: 1) {

        self.arrContacts[indexesOfStocksValue[i]] = iexEvents[i]
    }
}

並僅重新加載更新項目的行:

final func updateRows(stocksIndexes:[Int]) {

    DispatchQueue.main.async {

        self.stocktableView.performBatchUpdates({

            let indexesToUpdate = stocksIndexes.reduce([], { (currentResult, currentStocksIndex) -> [IndexPath] in

                if currentStocksIndex < self.stocktableView.numberOfRows(inSection: 0) {

                    return currentResult + [IndexPath.init(row: currentStocksIndex, section: 0)]
                }
                return currentResult
            })
            self.stocktableView.reloadRows(at: indexesToUpdate, with: UITableViewRowAnimation.automatic)
        }) { (_) in

        }
    }
}

現在,您可以使用該代碼更新行:

let indexesOfStocksValue = self.indexesOfStocks(stocks: iexEvents) // iexEvents is an array of Stocks
self.updateArrContacts(indexesOfStocksValue: indexesOfStocksValue, iexEvents: iexEvents)
self.updateRows(stocksIndexes: indexesOfStocksValue)

此解決方案基於以下想法: websocketDidReceiveMessage:之后websocketDidReceiveMessage:僅應更新arrContacts現有項目。 不會添加任何新項目,也不會刪除任何項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM