Search code examples
iosswiftsocketstcp

Swift Socket Sever disconnected while moving to one view controller to other


I am trying to implement swift socket in my application. I am pretty new to socket programming. I have used

https://github.com/swiftsocket/SwiftSocket

for socket connection. I had create NSObject class for Server Connection.

I want Server connected through out my whole application, But Server is disconnected while I'm moving into another ViewController.

class SocketGLobal : NSObject
{

func Connect()
    {
    let client = TCPClient(address: "www.apple.com", port: 80)
    switch client.connect(timeout: 1) {
      case .success:
        switch client.send(string: "GET / HTTP/1.0\n\n" ) {
          case .success:
            guard let data = client.read(1024*10) else { return }

            if let response = String(bytes: data, encoding: .utf8) {
              print(response)
            }
          case .failure(let error):
            print(error)
        }
      case .failure(let error):
        print(error)
      }
   }
}

Solution

  • I faced the same problem. So I created the custom ViewController and used GCDAsyncUdpSocket for socket connection. In your pod file add pod 'CocoaAsyncSocket' to use GCDAsyncUdpSocket. Here is the code snippet for custom ViewController.

    import CocoaAsyncSocket
    class CustomViewController: UIViewController, GCDAsyncUdpSocketDelegate {
        //MARK: VARIABLE DECLARATION **********
        var _udpSocket: GCDAsyncUdpSocket?
        var udpSocket: GCDAsyncUdpSocket? {
            get {
                if _udpSocket == nil {
                    let port = 80
                    let sock = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
                    do {
                        sock.setIPv6Enabled(false)
                        //                    sock?.setIPv4Enabled(true)
                        //                    sock?.setPreferIPv4()
                        try sock.enableBroadcast(true)
                        try sock.bind(toPort: UInt16(port))
                        try sock.beginReceiving()
    
                    } catch let err as NSError {
                        print(">>> Error while initializing socket: \(err.localizedDescription)")
                        sock.close()
                        return nil
                    }
                    _udpSocket = sock
                }
                return _udpSocket
            }
            set {
                _udpSocket?.close()
                _udpSocket = newValue
            }
        }
    
        //MARK: UDP SERVICES *********
        //Start UDP Receiver
        func startUDPService(){
            guard udpSocket != nil else {
                return
            }
        }
    
        //Stop UDP Receiver
        func closeUDPService(){
            if udpSocket != nil {                
                udpSocket?.close()
                udpSocket = nil                
            }
        }
    
        //MARK: HANDLING OF RECEIVED DATA **********
        func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
    
            var hostPtr : NSString? = nil
            GCDAsyncUdpSocket.getHost(&hostPtr, port: &send_port, fromAddress: address)
            var receivedText = ""
            if let stringData = String(data: data as Data, encoding: String.Encoding.utf8) {
                receivedText = stringData
            }
            print("Data received: \(String(describing: hostPtr)), \(receivedText)")
        }
    }
    

    In your each ViewController implement as follows:

    import UIKit
    class YourViewController: CustomViewController {
    
         //MARK: LIFE CYCLE METHODS **********
         override func viewWillAppear(_ animated: Bool) {
    
              //MARK: START UDP SERVICE
              self.startUDPService()
    
         }
    
         override func viewWillDisappear(_ animated: Bool) {
             //MARK: STOP UDP SERVICE
             self.closeUDPService()
         }
    }
    

    I hope this will help you.