I'm using socket.io to use the real-time mechanism. Problem that I'm facing right now is that Socket.io's object created after the viewController is loaded
I'm using Singleton design
import SocketIO
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
var socket: SocketIOClient!
func establishConnection() {
socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
socket.connect()
}
func closeConnection() {
socket.disconnect()
}
}
I need to set the socket in the establishConnection no matter what to make sure that user has establish the connection to the server together with the token. If I follow Vlad's answer, the connection will be never be established because the token is empty before hand thus user won't get connected.
User logs in
func logIn() {
// Getting it from alamofire
keychain["token"] = token
//then only establish connection
SocketIOManager.sharedInstance.establishConnection()
}
If I use Init method then the socket will be nil because in the applicationDidBecomeActive there's the SocketIOManager.sharedInstance.establishConnection(), so the logic is whenever user loads up the app the applicationDidBecomeActive will run
so technically I'm using sharedInstance to run the socket.io object.
func applicationDidBecomeActive(_ application: UIApplication) {
SocketIOManager.sharedInstance.establishConnection()
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
Right now the socket object in the didBecomeActive runs after the view loaded
override func viewDidLoad() {
super.viewDidLoad()
listeningOnMerchant()
}
func listeningOnMerchant() {
// I got error around here
SocketIOManager.sharedInstance.socket.on("listening") { ack, data in
print("something")
}
}
}
Which will crash because socket is nil. How do I make the viewController not crash. I could use the let method to stop the crash
if let socket = SocketIOManager.sharedInstance.socket {
}
But it will be nil if I use socket and socket won't be running. How do I not make the socket not crash?
Because i really need to put the socket.connect on applicationDidBecomeActive to make it consistent as in the connection vs didLaunch
Thanks!
Technically to solve this problem you need to use the init method so that the socket won't be nil. Since you need the socket to be running when the app paused and so on, you need to use the init method no matter what.
private override init() {
self.socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(true), .compress, .forceNew(true), .connectParams(["token": getToken()])])
super.init()
}
Add forceNew(true) so that you won't create multiple connections for one user
The next step you need to do is to create another function that only your loginViewController can access
func establishConnectionWhenLogin(_ token: String) {
self.socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": token])])
socket.connect()
}
pass the token to the parameter so that only user has logged in then you want to establish the connection. If you have any problems let me know
I use this solution for my own app and it works perfectly
As I understand, your problem is in setting SocketIOClient at the establishConnection func. If it crashes with nil, probably your constructor returns nil here:
SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
I don't see a reason also to do this inside this func. It's easy to make a mistake and leave socket var uninitialised at some point. I would rather make it let and set it inside of constructor, something like this:
import SocketIO
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
let socket: SocketIOClient!
init() {
super.init()
socket = YourFixedConstructorHere()
}
}
If you want to make sure it's initialised, you can also make it lazy var, like this:
lazy var socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With