Skip to content

Commit 158bdfb

Browse files
committed
Add enum for client events. Resolves #675
1 parent 1eb39d6 commit 158bdfb

File tree

4 files changed

+105
-12
lines changed

4 files changed

+105
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import SocketIO
99

1010
let socket = SocketIOClient(socketURL: URL(string: "http://localhost:8080")!, config: [.log(true), .forcePolling(true)])
1111

12-
socket.on("connect") {data, ack in
12+
socket.on(clientEvent: .connect) {data, ack in
1313
print("socket connected")
1414
}
1515

SocketIO-MacTests/SocketSideEffectTest.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,50 @@ class SocketSideEffectTest: XCTestCase {
177177
waitForExpectations(timeout: 0.2)
178178
}
179179

180+
func testOnClientEvent() {
181+
let expect = expectation(description: "The client should call client event handlers")
182+
let event = SocketClientEvent.disconnect
183+
let closeReason = "testing"
184+
185+
socket.on(clientEvent: event) {data, ack in
186+
guard let reason = data[0] as? String else {
187+
XCTFail("Client should pass data for client events")
188+
189+
return
190+
}
191+
192+
XCTAssertEqual(closeReason, reason, "The data should be what was sent to handleClientEvent")
193+
194+
expect.fulfill()
195+
}
196+
197+
socket.handleClientEvent(event, data: [closeReason])
198+
199+
waitForExpectations(timeout: 0.2)
200+
}
201+
202+
func testClientEventsAreBackwardsCompatible() {
203+
let expect = expectation(description: "The client should call old style client event handlers")
204+
let event = SocketClientEvent.disconnect
205+
let closeReason = "testing"
206+
207+
socket.on("disconnect") {data, ack in
208+
guard let reason = data[0] as? String else {
209+
XCTFail("Client should pass data for client events")
210+
211+
return
212+
}
213+
214+
XCTAssertEqual(closeReason, reason, "The data should be what was sent to handleClientEvent")
215+
216+
expect.fulfill()
217+
}
218+
219+
socket.handleClientEvent(event, data: [closeReason])
220+
221+
waitForExpectations(timeout: 0.2)
222+
}
223+
180224
let data = "test".data(using: String.Encoding.utf8)!
181225
let data2 = "test2".data(using: String.Encoding.utf8)!
182226
private var socket: SocketIOClient!

Source/SocketIOClient.swift

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
4848
break
4949
}
5050

51-
handleEvent("statusChange", data: [status], isInternalMessage: true)
51+
handleClientEvent(.statusChange, data: [status])
5252
}
5353
}
5454

@@ -204,11 +204,10 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
204204

205205
func didConnect() {
206206
DefaultSocketLogger.Logger.log("Socket connected", type: logType)
207+
207208
status = .connected
208209

209-
// Don't handle as internal because something crazy could happen where
210-
// we disconnect before it's handled
211-
handleEvent("connect", data: [], isInternalMessage: false)
210+
handleClientEvent(.connect, data: [])
212211
}
213212

214213
func didDisconnect(reason: String) {
@@ -221,7 +220,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
221220

222221
// Make sure the engine is actually dead.
223222
engine?.disconnect(reason: reason)
224-
handleEvent("disconnect", data: [reason], isInternalMessage: true)
223+
handleClientEvent(.disconnect, data: [reason])
225224
}
226225

227226
/// Disconnects the socket.
@@ -249,7 +248,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
249248
/// - parameter with: The items to send with this event. May be left out.
250249
open func emit(_ event: String, with items: [Any]) {
251250
guard status == .connected else {
252-
handleEvent("error", data: ["Tried emitting \(event) when not connected"], isInternalMessage: true)
251+
handleClientEvent(.error, data: ["Tried emitting \(event) when not connected"])
253252
return
254253
}
255254

@@ -302,7 +301,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
302301

303302
func _emit(_ data: [Any], ack: Int? = nil) {
304303
guard status == .connected else {
305-
handleEvent("error", data: ["Tried emitting when not connected"], isInternalMessage: true)
304+
handleClientEvent(.error, data: ["Tried emitting when not connected"])
306305
return
307306
}
308307

@@ -362,7 +361,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
362361
private func _engineDidError(reason: String) {
363362
DefaultSocketLogger.Logger.error("%@", type: logType, args: reason)
364363

365-
handleEvent("error", data: [reason], isInternalMessage: true)
364+
handleClientEvent(.error, data: [reason])
366365
}
367366

368367
/// Called when the engine opens.
@@ -399,6 +398,10 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
399398
}
400399
}
401400

401+
func handleClientEvent(_ event: SocketClientEvent, data: [Any]) {
402+
handleEvent(event.rawValue, data: data, isInternalMessage: true)
403+
}
404+
402405
/// Leaves nsp and goes back to the default namespace.
403406
open func leaveNamespace() {
404407
if nsp != "/" {
@@ -458,6 +461,30 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
458461
return handler.id
459462
}
460463

464+
/// Adds a handler for a client event.
465+
///
466+
/// Example:
467+
///
468+
/// ```swift
469+
/// socket.on(clientEvent: .connect) {data, ack in
470+
/// ...
471+
/// }
472+
/// ```
473+
///
474+
/// - parameter event: The event for this handler.
475+
/// - parameter callback: The callback that will execute when this event is received.
476+
/// - returns: A unique id for the handler that can be used to remove it.
477+
@discardableResult
478+
open func on(clientEvent event: SocketClientEvent, callback: @escaping NormalCallback) -> UUID {
479+
DefaultSocketLogger.Logger.log("Adding handler for event: %@", type: logType, args: event)
480+
481+
let handler = SocketEventHandler(event: event.rawValue, id: UUID(), callback: callback)
482+
handlers.append(handler)
483+
484+
return handler.id
485+
}
486+
487+
461488
/// Adds a single-use handler for an event.
462489
///
463490
/// - parameter event: The event name for this handler.
@@ -522,7 +549,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
522549
guard reconnecting else { return }
523550

524551
DefaultSocketLogger.Logger.log("Starting reconnect", type: logType)
525-
handleEvent("reconnect", data: [reason], isInternalMessage: true)
552+
handleClientEvent(.reconnect, data: [reason])
526553

527554
_tryReconnect()
528555
}
@@ -535,7 +562,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
535562
}
536563

537564
DefaultSocketLogger.Logger.log("Trying to reconnect", type: logType)
538-
handleEvent("reconnectAttempt", data: [(reconnectAttempts - currentReconnectAttempt)], isInternalMessage: true)
565+
handleClientEvent(.reconnectAttempt, data: [(reconnectAttempts - currentReconnectAttempt)])
539566

540567
currentReconnectAttempt += 1
541568
connect()

Source/SocketIOClientSpec.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,35 @@ protocol SocketIOClientSpec : class {
3434
func didError(reason: String)
3535
func handleAck(_ ack: Int, data: [Any])
3636
func handleEvent(_ event: String, data: [Any], isInternalMessage: Bool, withAck ack: Int)
37+
func handleClientEvent(_ event: SocketClientEvent, data: [Any])
3738
func joinNamespace(_ namespace: String)
3839
}
3940

4041
extension SocketIOClientSpec {
4142
func didError(reason: String) {
4243
DefaultSocketLogger.Logger.error("%@", type: "SocketIOClient", args: reason)
4344

44-
handleEvent("error", data: [reason], isInternalMessage: true, withAck: -1)
45+
handleClientEvent(.error, data: [reason])
4546
}
4647
}
48+
49+
/// The set of events that are generated by the client.
50+
public enum SocketClientEvent : String {
51+
/// Emitted when the client connects. This is also called on a successful reconnection.
52+
case connect
53+
54+
/// Called when the socket has disconnected and will not attempt to try to reconnect.
55+
case disconnect
56+
57+
/// Called when an error occurs.
58+
case error
59+
60+
/// Called when the client begins the reconnection process.
61+
case reconnect
62+
63+
/// Called each time the client tries to reconnect to the server.
64+
case reconnectAttempt
65+
66+
/// Called every time there is a change in the client's status.
67+
case statusChange
68+
}

0 commit comments

Comments
 (0)