Upgrading from v12
This guide will help you navigate the changes that were introduced in v13.
What are the big changes?
The biggest change is how to create and manage clients. Much like the native JS client and server, the swift client now only uses one engine per connection. Previously in order to use namespaces it was required to create multiple clients, and each client had its own engine.
Some v12 code might’ve looked like this:
let defaultSocket = SocketIOClient(socketURL: myURL)
let namespaceSocket = SocketIOClient(socketURL: myURL, config: [.nsp("/swift")])
// add handlers for sockets and connect
In v12 this would have opened two connections to the socket.io.
In v13 the same code would look like this:
let manager = SocketManager(socketURL: myURL)
let defaultSocket = manager.defaultSocket
let namespaceSocket = manager.socket(forNamespace: "/swift")
// add handlers for sockets and connect
In v13 defaultSocket
and namespaceSocket
will share a single transport. This means one less connection to the server
needs to be opened.
What might I have to change?
The most obvious thing you will need to change is that instead of creating
SocketIOClient
s directly, you will create aSocketManager
and either use thedefaultSocket
property if you don’t need namespaces, or call thesocket(forNamespace:)
method on the manager.SocketIOClient
is no longer a client to an engine. So if you were overriding the engine methods, these have been moved to the manager.The library is now a single target. So you might have to change some of your Xcode project settings.
SocketIOClient
s no longer take a configuration, they are shared from the manager.The
joinNamespace()
andleaveNamespace()
methods onSocketIOClient
no longer take any arguments, and in most cases no longer need to be called. Namespace joining/leaving can be managed by callingconnect()
/disconnect()
on the socket associated with that namespace.
What things should I know?
How sockets are stored
You should know that SocketIOClient
s no longer need to be held around in properties, but the SocketManager
should.
One of the most common mistakes people made is not maintaining a strong reference to the client.
class Manager {
func addHandlers() {
let socket = SocketIOClient(socketURL: myURL, config: [.nsp("/swift")])
// Add handlers
}
}
This would have resulted in the client being released and no handlers being called.
A correct equivalent would be:
class Manager {
let socketManager = SocketManager(socketURL: someURL)
func addHandlers() {
let socket = socketManager.socket(forNamespace: "/swift")
// Add handlers
}
}
This code is fine because the SocketManager
will maintain a strong reference to the socket.
It’s also worth noting that subsequent calls to socket(forNamespace:)
will return the same socket instance as the
first call. So you don’t need to hold onto the socket directly just to access it again, just call socket(forNamespace:)
on the manager to get it. This does mean that if you need multiple sockets on the same namespace, you will have to use
multiple managers.
What to call connect on
Connect can either be called on the manager directly, or on one of the sockets made from it. In either case, if the manager
was not already connected to the server, a connection will be made. Also in both cases the default socket (namespace “/”)
will fire a connect
event.
The difference is that if connect()
is just called on the manager, then any sockets for that manager that are not the default
socket will not automatically connect. connect()
will need to be called individually for each socket. However, if connect()
is called on a client, then in addition to opening the connection if needed, the client will connect to its namespace,
and a connect
event fired.