1

I'm trying to print the chat array that is declared as a empty global variable in a table. The data that I'm trying to print is received using web sockets. I'm assigning the data in the messageReceived function, and I know that the data is getting to the program because I'm printing in a label, but the moment that I'm trying to print it in the table is simple not working. All of this is in the ViewController.swift:

import UIKit
import Starscream

var messagetext: String = ""

var tabletext: String = ""

var chat = [String] ()

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {

var socket = WebSocket(url: URL(string: "ws://localhost:1337/")!, protocols: ["chat"])

@IBOutlet weak var chatMessage: UILabel!
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var tableView: UITableView!

@IBAction func buttonClick(_ sender: Any) {
    messagetext = textField.text!
    sendMessage(messagetext)
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.textField.delegate = self
    socket.delegate = self
    socket.connect()
    navigationItem.hidesBackButton = true
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
}

func textFieldDidEndEditing(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return (true)
}

deinit{
    socket.disconnect(forceTimeout: 0)
    socket.delegate = nil
}
}


// MARK: - FilePrivate
fileprivate extension ViewController {

func sendMessage(_ messager: String) {

    socket.write(string: messager)
}

func messageReceived(_ message: String) {

    chatMessage.text = message
    chat.append(message)
}
}

// MARK: - WebSocketDelegate
extension ViewController : WebSocketDelegate {
public func websocketDidConnect(_ socket: Starscream.WebSocket) {

}

public func websocketDidDisconnect(_ socket: Starscream.WebSocket, error: NSError?) {
    performSegue(withIdentifier: "websocketDisconnected", sender: self)
}

public func websocketDidReceiveMessage(_ socket: Starscream.WebSocket, text: String) {
    // 1
    guard let data = text.data(using: .utf16),
        let jsonData = try? JSONSerialization.jsonObject(with: data),
        let jsonDict = jsonData as? [String: Any],
        let messageType = jsonDict["type"] as? String else {
            return
    }

    // 2
    if messageType == "message",
        let messageData = jsonDict["data"] as? [String: Any],

        let messageText = messageData["text"] as? String {

        messageReceived(messageText)


    }
}

public func websocketDidReceiveData(_ socket: Starscream.WebSocket, data: Data) {

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return(chat.count)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
    cell.textLabel?.text = chat[indexPath.row] as! String

    return(cell)
}



}

3 Answers 3

1

Assuming that you are sure about there is data to be received by your view controller, The issue would be: the tableview data source methods are called before receiving any data, which means chat data source array is still empty, thus there is no data to display.

The solution for your case is to make sure to reload the tableview after receiving data (updating the value of chat data source array), which means in your case after appending a message to chat in messageReceived method by calling reloadData() UITableView instance method:

func messageReceived(_ message: String) {

    chatMessage.text = message
    chat.append(message)

    // here we go:
    tableView.reloadData()
}
Sign up to request clarification or add additional context in comments.

Comments

0

In your message received handler, issue a tableview.reloadData()

Cheers!

1 Comment

Or preferably, call insertRows to just add the new row; reloading the whole tableview is excessive
0

You need to tell the tableview that there is new data. You also need to allow for the fact that the network operation probably occurred on a background queue and UI updates must be on the main queue:

func messageReceived(_ message: String) {

    DispatchQueue.main.async {
        let newRow = IndexPath(row: chat.count, section:0)
        chatMessage.text = message
        chat.append(message)
        tableView.insertRows(at:[newRow],with: .automatic)
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.