I am able to connect to the server and receive message. When I send a message, in my logs I keep getting the message that the message is sent successfully, but it is not being reflected on the server’s log.
One fine day, it worked and I tried to build upon it but it didn’t work and I could not undo it either.
class ViewController: UIViewController {
@IBOutlet weak var ipAddress: UITextField!
@IBOutlet weak var portNumber: UITextField!
@IBOutlet weak var statusLabel: UILabel!
var connection: NWConnection?
var message: String?
override func viewDidLoad() {
super.viewDidLoad()
let backgroundImageView = UIImageView()
backgroundImageView.image = UIImage(named: "bg")
backgroundImageView.contentMode = .scaleAspectFill
backgroundImageView.frame = view.bounds
view.insertSubview(backgroundImageView, at: 0)
let hideKeyboard = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
view.addGestureRecognizer(hideKeyboard)
}
@IBAction func connectTapped(_ sender: Any) {
guard let ipAddress = ipAddress.text, !ipAddress.isEmpty else {
makeAlert(titleInput: "Error!", messageInput: "Please enter IP Address")
return
}
guard let portText = portNumber.text, let port = UInt16(portText), !portText.isEmpty else {
makeAlert(titleInput: "Error!", messageInput: "Please enter port number")
return
}
self.connectToServer(ipAddress: ipAddress, port: port)
}
//**Connection to Server**
func connectToServer(ipAddress: String, port: UInt16) {
let host = NWEndpoint.Host(ipAddress)
let port = NWEndpoint.Port(rawValue: port)!
connection = NWConnection(host: host, port: port, using: .tcp)
connection?.stateUpdateHandler = { [weak self] newState in
switch newState {
case .ready:
DispatchQueue.main.async {
self?.statusLabel.text = "Connected to server."
self?.receiveMessage()
}
case .failed(let error):
DispatchQueue.main.async {
self?.statusLabel.text = "Failed to connect: (error.localizedDescription)"
}
self?.connection?.cancel()
self?.connection = nil
default:
break
}
}
connection?.start(queue: .global(qos: .background))
}
func makeAlert(titleInput: String, messageInput: String, completion: (() -> Void)? = nil) {
let alert = UIAlertController(title: titleInput, message: messageInput, preferredStyle: .alert)
let okButton = UIAlertAction(title: "Okay", style: .default) { _ in
completion?()
}
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
}
// **receive Message**
func receiveMessage() {
connection?.receive(minimumIncompleteLength: 1, maximumLength: 1024) { [weak self] data, context, isComplete, error in
if let data = data, !data.isEmpty {
self?.message = String(data: data, encoding: .utf8) ?? "Received data, but cannot decode."
DispatchQueue.main.async {
self?.makeAlert(titleInput: "Message received", messageInput: "(self?.message ?? "no message")") {
if let messageToSend = self?.message {
self?.sendMessage(messageToSend)
}
}
}
}
if isComplete {
self?.connection?.cancel()
self?.connection = nil
} else if let error = error {
DispatchQueue.main.async {
self?.statusLabel.text = "Receive error: (error.localizedDescription)"
}
self?.connection?.cancel()
self?.connection = nil
} else {
self?.receiveMessage()
}
}
}
// **send Message**
func sendMessage(_ message: String) {
guard let connection = connection else {
print("Connection is not established")
DispatchQueue.main.async {
self.statusLabel.text = "Connection is not established"
}
return
}
guard let data = message.data(using: .utf8) else {
print("Failed to encode message to data")
DispatchQueue.main.async {
self.statusLabel.text = "Failed to encode message to data"
}
return
}
print("Sending message: (message)")
connection.send(content: data, completion: .contentProcessed({ [weak self] error in
if let error = error {
print("Failed to send data: (error.localizedDescription)")
DispatchQueue.main.async {
self?.statusLabel.text = "Send error: (error.localizedDescription)"
}
return
}
print("Data sent successfully")
DispatchQueue.main.async {
self?.makeAlert(titleInput: "Sent successfully", messageInput: "Sending message") {
}
self?.statusLabel.text = "Data sent successfully"
}
}))
}
@objc func hideKeyboard(gestureRecognizer: UITapGestureRecognizer) {
view.endEditing(true)
}
}
Expected behaviour:
On the viewController, I enter the IP address and port, click on “Connect” button. I receive a “JSON” on an UIAlertController. Upon tapping the “OK” button it sends a string.
Actual behaviour:
everything is working fine and upon tapping the “OK” button, I see “message sent successfully” on my log, but on the server device’s it only shows connection but no message is received there.
Gurpreet Singh is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.