Ben*_*n10 3 uitableview websocket ios swift
我有 websocket 服务器,该服务器根据我的订阅每两秒推送一次数据。我需要根据 tableview.currently 更新行,我正在使用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:仅arrContacts应更新现有项目之后。不会添加任何新项目,也不会删除任何项目。
| 归档时间: | 
 | 
| 查看次数: | 1478 次 | 
| 最近记录: |