# 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: ```swift 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: ```swift 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 a `SocketManager` and either use the `defaultSocket` property if you don't need namespaces, or call the `socket(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. ---------- # 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. ```swift 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: ```swift 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 the its namespace, and a `connect` event fired.