0

I am trying to build an app that communicates with a TCP server on my network.

The code I am using is this:

let addr = "192.168.1.104"
let port = 101010
var inp: NSInputStream?
var out: NSOutputStream?

@IBAction func Connect_Button(sender: AnyObject) {
     NSStream.getStreamsToHostWithName(addr, port: port, inputStream: &inp, outputStream: &out)
    let inputStream = inp!
    let outputStream = out!

    inputStream.open()
    outputStream.open()

    var buffer: [UInt8] = [92,72,69,76,76,79,49,50,51,33,47] //"\Hello123!/" in ASCII - hardcoded to test.
    outputStream.write(&buffer, maxLength: buffer.count)
    let bufferSize = 1024
    var inputBuffer = Array<UInt8>(count:bufferSize, repeatedValue: 0)

    let bytesRead = inputStream.read(&inputBuffer, maxLength: bufferSize)
    //encode as string and print
    var readByte :UInt8 = 0

    Current_Text.text = ""
    while inputStream.hasBytesAvailable {
        Current_Text.text? += String(inputStream.read(&inputBuffer, maxLength: 1))
    }
}

I won't put the link in, in case it breaks any rules. But it's from a Reddit post.

Issue 1) When I press my UIButton to trigger the communication, it fails almost all the time. Out of 10 tests, I get 3 successful transmissions and 7 "hangs". Not sure what causes these "hangs" in communication but it requires me to quit the app and re-run.

Issue 2) The string that my server returns ("OK", "ERROR"...) aren't being read by my code either. I think this is due to my lack of knowledge though. I am still reading up on how this works.

Issue 3) I need this communication code to go on a different program thread as everything halts whilst it's executing. Can this code run on dispatch_async? At present I am directly testing the code in an IBAction but I intend to put it in a class/function (separate swift file) and then return the data.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Rs2845
  • 53
  • 1
  • 6
  • Using a synchronous approach like this isn't very efficient and will give you problems as you are finding. For example, your method exits (tearing down the whole connection since you are using local variables) as soon as there are no bytes available - even if there will be bytes available in a few milliseconds. You need to use an asynchronous approach such as AFNetworking – Paulw11 Jan 03 '16 at 22:19
  • @Paulw11 thanks for your advice. I have seen one example online which uses GET and PUT. How would I use AFNetworking in a swift project and interact with a TCP server? Finding my original code was hard enough haha – Rs2845 Jan 03 '16 at 22:49
  • If you aren't using HTTP then CocoaAsyncSocket is probably better - https://github.com/robbiehanson/CocoaAsyncSocket – Paulw11 Jan 04 '16 at 00:28
  • @Paulw11 - thanks for your suggestion. As mentioned before I am very new to swift and have just managed to get to grips on how to build a simple app and watchOS app. I haven't been able to find an example project implementing a TCP client in Swift or how to even create my own function using Cocoaasyncsocket. Can't believe how many hours I have spent scouring the net on something I expected to be much simpler. How wrong I was – Rs2845 Jan 05 '16 at 02:25

0 Answers0