Search code examples
swiftxcodemodel-view-controllerviewcontroller

Calling ViewController function from another .swift file


I have a collectionView that I want to reloadData() once certain data is received. The problem is: I don't know how to call ViewController function from another .swift file that handles the data. I tried doing:

class WebSocketLogic: WebSocketDelegate {
    var viewController = ViewController()
    var columns = 0
    var rows = 0
...
    func receiveData {
        ...
        columns = map.count
        rows = map[0].count
        viewController.collectionView.reloadData()
    }
}

It gave me Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeec870fe8) error on ViewController() initializing line.
I also tried doing:

class ViewController: UIViewController {
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    var webSocket = WebSocketLogic(roomId: 1)
    var columns = 0 {
        didSet {
            collectionView.reloadData()
            print("columns number set to: \(columns)")
        }
    }
    var rows = 0  

    override func viewDidLoad() {
        super.viewDidLoad()
        
        webSocket.setupStarScream()
        columns = webSocket.columns
        rows = webSocket.rows
    }
}

But for some reason the didSet only gets called once and in the very beginning. What can I do to call reloadData() in ViewController once receiveData()func is completed in another file?


Solution

  • You can use delegation pattern

    protocol DataDelegate {
        func dataReceived()
    }
    
    class WebSocketLogic: WebSocketDelegate {
        var delegate: DataDelegate?
        var columns = 0
        var rows = 0
    ...
        func receiveData {
            ...
            columns = map.count
            rows = map[0].count
            delegate?.dataReceived()
        }
    }
    
    class ViewController: UIViewController, DataDelegate {
        
        @IBOutlet weak var collectionView: UICollectionView!
        
        var webSocket = WebSocketLogic(roomId: 1)
        var columns = 0 {
            didSet {
                collectionView.reloadData()
                print("columns number set to: \(columns)")
            }
        }
        var rows = 0  
    
        override func viewDidLoad() {
            super.viewDidLoad()
            webSocket.delegate = self
            
            webSocket.setupStarScream()
            columns = webSocket.columns
            rows = webSocket.rows
        }
       
        func dataReceived() {
            collectionView.reloadData()
        }
    }