TCP Socket in Swift

Marzukr picture Marzukr · Sep 7, 2014 · Viewed 9.3k times · Source

I am trying to write a TCP socket client in swift using GCDAsyncSocket, but I am having a lot of problems. In my code I have a NSTextField (called box) and here is my code: import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate 
{

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var box: NSTextField!

    let bsocket = GCDAsyncSocket(delegate: AppDelegate.self, delegateQueue: dispatch_get_main_queue())

    func applicationDidFinishLaunching(aNotification: NSNotification?)
    {
        var port:UInt16 = 8090
        if (!bsocket.connectToHost("localhost", onPort: port, error: nil))
        {
            println("Error")
        }
        else
        {
            println("Connecting...")
        }
        var request:String = "Arn.Preg:3302:"
        var data:NSData = request.dataUsingEncoding(NSUTF8StringEncoding)!
        bsocket.writeData(data, withTimeout: -1.0, tag: 0)
        bsocket.readDataWithTimeout(-1.0, tag: 0)
    }

    func applicationWillTerminate(aNotification: NSNotification?) 
    {
        // Insert code here to tear down your application
    }

    func socket(socket : GCDAsyncSocket, didReadData data:NSData, withTag tag:UInt16)
    {
        var response = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Received Response")
        box.stringValue = box.stringValue + "\n" + response
    }

    func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16)
    {
        println("Connected to \(host) on port \(p).")
        box.stringValue = box.stringValue + "\n" + "Connected to \(host) on port \(p)."
    }
}

When I run the code, what I want it to do is display the text that the TCP server returns in the text box, but for some reason, the function

func socket(socket : GCDAsyncSocket, didReadData data:NSData, withTag tag:UInt16)

Never gets run. When I use the telnet command in the terminal to achieve the same result, the server returns this:

Marzuk:~ marzukrashid$ telnet localhost 8090
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Arn.TipoSer:XPL0:

Then, when I type in "Arn.Preg:3302:", the server returns this:

Marzuk:~ marzukrashid$ telnet localhost 8090
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Arn.TipoSer:XPL0:
Arn.Preg:3302:
Arn.Resp:3302=329351:

When I type in "Arn.Preg:3302:" the server returns "Arn.Resp:3302=329351:", this is the result I am trying to achieve, I want the NSTextField in my application to display "Arn.Resp:3302=329351:".

My question is why is my code not doing this, and how can I fix my code into doing this.

Thanks.

Edit: When I run the program, the NSTextField is empty and the program prints "Connecting..." but it does not print "Connected" or anything else.

Answer

Nate Cook picture Nate Cook · Sep 8, 2014

The self in your socket initializer isn't what you think -- it's actually a reference to the Type of your AppDelegate. Try moving that initialization inside applicationDidFinishLaunching().

class AppDelegate: NSObject, NSApplicationDelegate 
{

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var box: NSTextField!
    var bsocket: GCDAsyncSocket!

    func applicationDidFinishLaunching(aNotification: NSNotification?)
    {
        bsocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
        // ...