Socket.io-client-swift: Can't emit a dictionary

Created on 9 Nov 2016  路  12Comments  路  Source: socketio/socket.io-client-swift

Our socket.io api is expecting a dictionary as the top level object, but all of the emit calls in socket.io-swift only accept an array of items.

Server is expecting

    {
        token: abcdefg
        version: 1.1.0
    }

Server is getting

    [{
        token: abcdefg
        version: 1.1.0
    }]

Proposal: add another emit method that accepts non-array items.

Most helpful comment

Right, and in the socket.io protocol data is sent in the format 2["someEvent", arg1, arg2, arg3]. Which is why I do https://github.com/socketio/socket.io-client-swift/blob/master/Source/SocketIOClient.swift#L211.

So that when it gets to https://github.com/socketio/socket.io-client-swift/blob/master/Source/SocketPacket.swift#L89 it turns it into that proper format.

All 12 comments

How are you emitting?

My emit call looked like this:

    let authDict = ["token": self.keychainManager.token,
                  "version": "1.1.0"]
    self.io.emit("authentication", authDict)

I've submitted a PR: #572

You can see the issue here:

public func emit(_ event: String, _ items: SocketData...) {...}
public func emitWithAck(_ event: String, _ items: SocketData...) -> OnAckCallback {...}

both emit methods only accept arrays of SocketData.

Right but that's because you can do

socket.emit("someEvent", 1, {"test": 1}, true)

And then do

socket.on("someEvent", (int, obj, bool) => { })

In JavaScript.

If you're getting something enclosed in an array that means something is broken with the encoder. Either they've changed the socket.io protocol on me or something else is going on.

In Swift when you define a parameter in a method like items: SocketData... items automatically becomes an array.

from the docs:

The values passed to a variadic parameter are made available within the function鈥檚 body as an array of the appropriate type.

So even for a single item passed in to the method (in my case, a dictionary) it gets stored in an array.

Right, and in the socket.io protocol data is sent in the format 2["someEvent", arg1, arg2, arg3]. Which is why I do https://github.com/socketio/socket.io-client-swift/blob/master/Source/SocketIOClient.swift#L211.

So that when it gets to https://github.com/socketio/socket.io-client-swift/blob/master/Source/SocketPacket.swift#L89 it turns it into that proper format.

And there are tests for the parsing and encoding, so I would hope I would catch failures if it's a code change that broke something.

Turns out I was calling the wrong method in my own code. Instead of calling this I should've been calling this from my own methods since my own method already wrapped the arguments in an array.

I apologize for my hastiness. Thanks for helping me troubleshoot this. I closed my PR since it's not necessary anymore.

Yeah the reason there are two methods is to take advantage of Swift's variadic parameters so make the api more like the JavaScript client.

Was this page helpful?
0 / 5 - 0 ratings