Issue trying to work with NWConnection in Network.Framework

1.1k Views Asked by At

I am writing an application which sends commands and receives data via UDP network connection with a device.

I am trying to create an object which handles all the network related tasks.

I want the object to make a connection, send a command string to the connection, and receive data from the connection. I can get all the pieces to work but they happen out of sync with the running program. It is hard to explain but let me show you the code first then explain the issue.

import Foundation
import Network

var myConnection: NWConnection?
var backToString = "test"

class NetworkUDP: NSObject{

    func makeConnection(){
        
        let myPort = NWEndpoint.Port(rawValue: 50536)
        let myHost = NWEndpoint.Host("192.168.7.239")
        
        myConnection = NWConnection(host: myHost, port: myPort!, using: .udp)
        myConnection?.start(queue: .main)
        
    }
    
    func send(myCommand: String) {
        myConnection?.send(content: myCommand.data(using: String.Encoding.utf8), completion: NWConnection.SendCompletion.contentProcessed({(NWError) in  print(NWError as Any)}))
        print(myCommand)
    }
    
    func receive() {
        
        myConnection?.receiveMessage { (data, context, isComplete, error) in
            if (data != nil) {
                backToString = String(decoding: data!, as : UTF8.self)
                print(backToString)
            } else {
                print("Data = nil")
            }
        }
    }
}

So if I instantiate this object and issue makeConnection(), send(myCommand: aCommand), receive() statements from a ViewController everything works but the functions run and return before the commands are actually sent and values returned.

In other words, I can't return the value of backToString as a return value from the function receive(). If I do it will always return "test" which is the initial value. It will eventually be replaced with the string value returned from the device but only after a delay and only after the function has already returned.

What I want to do is make a receive function of the form receive() -> String where String is the text string returned from the device that was sent a command. But I guess this isn't possible because the receive function returns before backToString actually receives any data. I am a bit confused by this. It seems like the function should stay halted until a value is received but it doesn't it just returns before the backToString variable receives the data from the UDP connection. However the print statement in the receive function does print the correct data but it only does so after the function receive has already returned.

0

There are 0 best solutions below