Non-responsive stream delegate in Swift
Asked Answered
M

1

7

So I was playing around with sockets in Swift and trying to connect the app with my server. I was having the app connect to the IP address of the server and used netcat on the server for testing. During execution, the console output from the app showed it had successfully connected to the server. However, the stream delegate does not seem to be responsive. When I typed into netcat, the app console did not print anything. I have searched for quite a while and found that my implementation is pretty similar to others. Perhaps I am missing something here that I do not see.

Any thought to this problem would be greatly appreciated!

Code is attached below:

import UIKit

class ViewController: UIViewController, StreamDelegate {

    let addr:String = "52.34.56.78"
    let port:Int = 1234

    var inputStream: InputStream?
    var outputStream: OutputStream?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.connect(host: addr, port: port)
    }

    func connect(host: String, port: Int) {

        Stream.getStreamsToHost(withName: host, port: port, inputStream: &inputStream, outputStream: &outputStream)

        if inputStream != nil && outputStream != nil {

            inputStream!.delegate = self
            outputStream!.delegate = self

            inputStream!.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)
            outputStream!.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)

            inputStream!.open()
            outputStream!.open()

            print("successfully connected")
        }
        else {
            print("connection unsuccessful")
        }
    }

    func stream(aStream: Stream, handleEvent eventCode: Stream.Event) {

        if aStream === inputStream {
            switch eventCode {
            case Stream.Event.errorOccurred:
                print("input: ErrorOccurred: \(aStream.streamError?.localizedDescription)")
                break
            case Stream.Event.openCompleted:
                print("input: OpenCompleted")
                break
            case Stream.Event.hasBytesAvailable:
                print("input: HasBytesAvailable")
                break
            default:
                break
            }
        }
        else {
            print("unknown stuff happened")
        }
    }
}
Malraux answered 14/12, 2016 at 0:34 Comment(1)
So it seems like the app was able to connect to the server, but the stream() function was not triggered at all. When I checked for inputStream.hasBytesAvailable, it returned true after I sent something via netcat. I suspect this has something to do with not properly configuring the stream delegate, or maybe the run loop.Malraux
M
12

So after a lot of trials and errors, I finally realized the stream() function did not work just because the signature of this function is incorrect/obsolete.

Here is what I was using:

func stream(aStream: Stream, handleEvent eventCode: Stream.Event)

But really it should be:

func stream(_ aStream: Stream, handle eventCode: Stream.Event)

This is likely a syntax conversion from previous Swift version to Swift 3. The XCode compiler usually detects obsolete functions/syntax, but sadly did not catch this one.

Hopefully my answer could help out those who are still suffering from this problem.

Malraux answered 16/12, 2016 at 0:15 Comment(7)
I have been trying to figure out this problem for a long time as well; thanks for postingPolecat
do you know how you would flush after the buffer is full?Polecat
Glad that I can help! I guess you can put a loop in your read() function. So basically whenever there's bytes available to read, your read() function should be working. You can also set a buffer size limit, so that whenever read() is done processing x number of bytes, you can proceed with your parsing without having to wait for the entire response to be received.Malraux
This was helpful to me in sorting out an issue I was having with this under Linux. In that context, Swift still wants the old signature.Liber
You sir, deserve a medal. I'm really surprised so little documentation about this existsHugohugon
thanks a lot it helps me too ..and one Question how can I return something in connect func after delegate func triggered..Realist
Using Swift 5.x, problem still there, doesn't detect wrong syntax.Nadbus

© 2022 - 2024 — McMap. All rights reserved.