Delegated functions not working outside of UIViewController

332 Views Asked by At

I'm using the Startscream Websocket framework. Everything works fine as long as I keep all of the code in a UIViewController as seen here. But as soon as a create a wrapper class for Startscream all of the delegated functions stop working. Also my local websocket server is not getting a connection.

How can I get the code working inside a wrapper class?

MyService.swift:

import Starscream

public class MyService: WebSocketDelegate {
    var socket = WebSocket(url: URL(string: "ws://localhost:3900/websocket")!)

    func connect() {
        socket.delegate = self
        socket.connect()
        print("Connecting")
    }

    // MARK: Websocket Delegate Methods.

    public func websocketDidConnect(socket: WebSocket) {
        print("websocket is connected")
    }

    public func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
        if let e = error {
            print("websocket is disconnected: \(e.localizedDescription)")
        } else {
            print("websocket disconnected")
        }
    }

    public func websocketDidReceiveMessage(socket: WebSocket, text: String) {
        print("Received text: \(text)")
    }

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

    // MARK: Write Text Action

    @IBAction func writeText(_ sender: UIBarButtonItem) {
        socket.write(string: "hello there!")
    }

    // MARK: Disconnect Action

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

}

ViewController.swift:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let service = MyService()
        service.connect()
    }

}
2

There are 2 best solutions below

1
Rob Fox On BEST ANSWER

The reference to Service in ViewController was not stored anywhere so as soon as the function was run it was cleaned up. This is how I fixed it:

class ViewController: UIViewController {

    var service = MyService()

    override func viewDidLoad() {
        super.viewDidLoad()
        service.connect()
    }

    ...
2
Woof On

I'm not sure what is wrong with your code, it can be an endpoint issue, or WS is not allocated somehow. I have same code with Starscream working in Swift 3, here is the main part of my class.

class ConnectionManager {
    private var savedSocket: WebSocket?
    fileprivate var socket: WebSocket {

        if let saved = savedSocket {
            return saved
        }

        let wsURL = URL(string: UserDefaultsManager.wsURLString)!

        savedSocket = WebSocket(url: wsURL)

        return savedSocket!
    }

    func startSession() {

        if (socket.isConnected) { return }
        socket.headers = headers
        socket.delegate = self

        socket.connect()
    }

    func endSession() {

        if (socket.isConnected) {
            socket.disconnect()
        }

    }
}

extension ConnectionManager: WebSocketDelegate {
    func websocketDidConnect(socket: WebSocket) {

    }

    func websocketDidDisconnect(socket: WebSocket, error: NSError?){
        if let e = error {
            log.error("websocket is disconnected with ERROR: \(e.localizedDescription)")
        } else {
            log.error("websocket disconnected")
        }

    }

    func websocketDidReceiveMessage(socket: WebSocket, text: String){

    }

    func websocketDidReceiveData(socket: WebSocket, data: Data){

    }
}

My code is not a best practise for sure, but it works without any problem. Try to use my version, maybe it will work for you.