Description
Environment:
Library Version: 16.1.0
Xcode: tested on Xcode 14 and Xcode 15
Platform: iOS 16 and iOS 17
Description:
I've encountered an issue with the emitWithAck
function in the Socket.IO-Client-Swift library, specifically when using the timingOut(after:)
closure. The OnAckCallback
object returned by emitWithAck
seems to get deallocated prematurely if not explicitly retained in the client code.
In addition to the premature deallocation of the OnAckCallback
instance, a critical part of the issue is that the callback code socket.ackHandlers.timeoutAck(self.ackNumber)
within the timingOut(after:)
function is never executed as expected. This is because self
(referring to the OnAckCallback
instance) becomes nil
after the timeout period elapses. This behavior results in the failure of the timeout handling logic, as the necessary callback for a timeout situation is not called.
Steps to Reproduce:
- Call
emitWithAck().timingOut(after:)
on aSocketIOClient
instance. Make sure server doesnt send any callbacks. - Observe that the
OnAckCallback
instance is deallocated before the timeout closure is executed, resulting inself
beingnil
within the closure.
Expected Behavior:
The OnAckCallback
instance should be retained internally by the library until the timingOut(after:)
closure is executed or the timeout occurs.
Actual Behavior:
The OnAckCallback
instance is deallocated prematurely unless explicitly retained in the client code.
My hacky fix
In my current SocketHandler class, i've added a var emitAckCallBack: OnAckCallback?
which i assign the value of socket.emitWithAck()
and afterwards i call emitAckCallBack?.timingOut(after:)
and thereafter set the emitAckCallBack
to nil inside the completion block. This seems to hold a reference to OnAckCallback
which prevents it from getting deallocated prematurely.
Code example:
var emitAckCallBack: OnAckCallback?
func send() {
emitAckCallBack = self.socket.emitWithAck("send_event", "test")
emitAckCallBack?.timingOut(after: 2) { data in
print("Ack received with data: \(data)")
}
}