Skip to content

Commit 31aed9e

Browse files
committed
Merge branch 'development'
* development: update changelog Remove MARK: for websockets methods Use callbacks instead of delegate methods for Starscream Fix exclusive access issue Execute acks sync. Implement #950 Fixes build warnings caused by documentation issues. update starscream carthage
2 parents d388e1c + 4e55883 commit 31aed9e

14 files changed

+81
-69
lines changed

.swift-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.0.2
1+
system

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
# 13.1.1
1+
# v13.1.2
2+
3+
- Fix [#950](https://github.com/socketio/socket.io-client-swift/issues/950)
4+
- Conforming to `SocketEngineWebsocket` no longer requires conforming to `WebsocketDelegate`
5+
6+
7+
# v13.1.1
28

39
- Fix [#923](https://github.com/socketio/socket.io-client-swift/issues/923)
410
- Fix [#894](https://github.com/socketio/socket.io-client-swift/issues/894)

Cartfile.resolved

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1+
github "daltoniam/Starscream" "3.0.3"
12
github "daltoniam/common-crypto-spm" "1.1.0"
23
github "daltoniam/zlib-spm" "1.1.0"
3-
github "daltoniam/Starscream" "3.0.2"

Source/SocketIO/Ack/SocketAckEmitter.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public final class OnAckCallback : NSObject {
108108

109109
/// Completes an emitWithAck. If this isn't called, the emit never happens.
110110
///
111-
/// - parameter after: The number of seconds before this emit times out if an ack hasn't been received.
111+
/// - parameter seconds: The number of seconds before this emit times out if an ack hasn't been received.
112112
/// - parameter callback: The callback called when an ack is received, or when a timeout happens.
113113
/// To check for timeout, use `SocketAckStatus`'s `noAck` case.
114114
@objc
@@ -121,9 +121,9 @@ public final class OnAckCallback : NSObject {
121121
guard seconds != 0 else { return }
122122

123123
socket.manager?.handleQueue.asyncAfter(deadline: DispatchTime.now() + seconds) {[weak socket] in
124-
guard let socket = socket, let manager = socket.manager else { return }
124+
guard let socket = socket else { return }
125125

126-
socket.ackHandlers.timeoutAck(self.ackNumber, onQueue: manager.handleQueue)
126+
socket.ackHandlers.timeoutAck(self.ackNumber)
127127
}
128128
}
129129

Source/SocketIO/Ack/SocketAckManager.swift

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,31 +58,20 @@ private struct SocketAck : Hashable {
5858
}
5959
}
6060

61-
struct SocketAckManager {
61+
class SocketAckManager {
6262
private var acks = Set<SocketAck>(minimumCapacity: 1)
63-
private let ackSemaphore = DispatchSemaphore(value: 1)
6463

65-
mutating func addAck(_ ack: Int, callback: @escaping AckCallback) {
64+
func addAck(_ ack: Int, callback: @escaping AckCallback) {
6665
acks.insert(SocketAck(ack: ack, callback: callback))
6766
}
6867

6968
/// Should be called on handle queue
70-
mutating func executeAck(_ ack: Int, with items: [Any], onQueue: DispatchQueue) {
71-
ackSemaphore.wait()
72-
defer { ackSemaphore.signal() }
73-
let ack = acks.remove(SocketAck(ack: ack))
74-
75-
onQueue.async() { ack?.callback(items) }
69+
func executeAck(_ ack: Int, with items: [Any]) {
70+
acks.remove(SocketAck(ack: ack))?.callback(items)
7671
}
7772

7873
/// Should be called on handle queue
79-
mutating func timeoutAck(_ ack: Int, onQueue: DispatchQueue) {
80-
ackSemaphore.wait()
81-
defer { ackSemaphore.signal() }
82-
let ack = acks.remove(SocketAck(ack: ack))
83-
84-
onQueue.async() {
85-
ack?.callback?([SocketAckStatus.noAck.rawValue])
86-
}
74+
func timeoutAck(_ ack: Int) {
75+
acks.remove(SocketAck(ack: ack))?.callback?([SocketAckStatus.noAck.rawValue])
8776
}
8877
}

Source/SocketIO/Client/SocketIOClient.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
7575
}
7676
}
7777

78-
var ackHandlers = SocketAckManager()
78+
let ackHandlers = SocketAckManager()
7979

8080
private(set) var currentAck = -1
8181

@@ -86,7 +86,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
8686
/// Type safe way to create a new SocketIOClient. `opts` can be omitted.
8787
///
8888
/// - parameter manager: The manager for this socket.
89-
/// - parameter socketURL: The url of the socket.io server.
89+
/// - parameter nsp: The namespace of the socket.
9090
@objc
9191
public init(manager: SocketManagerSpec, nsp: String) {
9292
self.manager = manager
@@ -115,7 +115,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
115115
///
116116
/// - parameter timeoutAfter: The number of seconds after which if we are not connected we assume the connection
117117
/// has failed. Pass 0 to never timeout.
118-
/// - parameter withHandler: The handler to call when the client fails to connect.
118+
/// - parameter handler: The handler to call when the client fails to connect.
119119
@objc
120120
open func connect(timeoutAfter: Double, withHandler handler: (() -> ())?) {
121121
assert(timeoutAfter >= 0, "Invalid timeout: \(timeoutAfter)")
@@ -213,7 +213,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
213213
/// Same as emit, but meant for Objective-C
214214
///
215215
/// - parameter event: The event to send.
216-
/// - parameter with: The items to send with this event. Send an empty array to send no data.
216+
/// - parameter items: The items to send with this event. Send an empty array to send no data.
217217
@objc
218218
open func emit(_ event: String, with items: [Any]) {
219219
guard status == .connected else {
@@ -270,7 +270,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
270270
/// ```
271271
///
272272
/// - parameter event: The event to send.
273-
/// - parameter with: The items to send with this event. Use `[]` to send nothing.
273+
/// - parameter items: The items to send with this event. Use `[]` to send nothing.
274274
/// - returns: An `OnAckCallback`. You must call the `timingOut(after:)` method before the event will be sent.
275275
@objc
276276
open func emitWithAck(_ event: String, with items: [Any]) -> OnAckCallback {
@@ -314,11 +314,11 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
314314
/// - parameter data: The data sent back with this ack.
315315
@objc
316316
open func handleAck(_ ack: Int, data: [Any]) {
317-
guard status == .connected, let manager = self.manager else { return }
317+
guard status == .connected else { return }
318318

319319
DefaultSocketLogger.Logger.log("Handling ack: \(ack) with data: \(data)", type: logType)
320320

321-
ackHandlers.executeAck(ack, with: data, onQueue: manager.handleQueue)
321+
ackHandlers.executeAck(ack, with: data)
322322
}
323323

324324
/// Called on socket.io specific events.
@@ -334,7 +334,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
334334
/// - parameter event: The name of the event.
335335
/// - parameter data: The data that was sent with this event.
336336
/// - parameter isInternalMessage: Whether this event was sent internally. If `true` it is always sent to handlers.
337-
/// - parameter withAck: If > 0 then this event expects to get an ack back from the client.
337+
/// - parameter ack: If > 0 then this event expects to get an ack back from the client.
338338
@objc
339339
open func handleEvent(_ event: String, data: [Any], isInternalMessage: Bool, withAck ack: Int = -1) {
340340
guard status == .connected || isInternalMessage else { return }

Source/SocketIO/Client/SocketIOClientSpec.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public protocol SocketIOClientSpec : class {
5959
///
6060
/// - parameter timeoutAfter: The number of seconds after which if we are not connected we assume the connection
6161
/// has failed. Pass 0 to never timeout.
62-
/// - parameter withHandler: The handler to call when the client fails to connect.
62+
/// - parameter handler: The handler to call when the client fails to connect.
6363
func connect(timeoutAfter: Double, withHandler handler: (() -> ())?)
6464

6565
/// Called when the client connects to a namespace. If the client was created with a namespace upfront,
@@ -134,7 +134,7 @@ public protocol SocketIOClientSpec : class {
134134
/// - parameter event: The name of the event.
135135
/// - parameter data: The data that was sent with this event.
136136
/// - parameter isInternalMessage: Whether this event was sent internally. If `true` it is always sent to handlers.
137-
/// - parameter withAck: If > 0 then this event expects to get an ack back from the client.
137+
/// - parameter ack: If > 0 then this event expects to get an ack back from the client.
138138
func handleEvent(_ event: String, data: [Any], isInternalMessage: Bool, withAck ack: Int)
139139

140140
/// Causes a client to handle a socket.io packet. The namespace for the packet must match the namespace of the

Source/SocketIO/Engine/SocketEngine.swift

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -280,18 +280,40 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
280280
}
281281

282282
private func createWebSocketAndConnect() {
283-
ws?.delegate = nil // TODO this seems a bit defensive, is this really needed?
284283
var req = URLRequest(url: urlWebSocketWithSid)
285284

286285
addHeaders(to: &req)
287286

288287
ws = WebSocket(request: req)
289288
ws?.callbackQueue = engineQueue
290289
ws?.enableCompression = compress
291-
ws?.delegate = self
292290
ws?.disableSSLCertValidation = selfSigned
293291
ws?.security = security?.security
294292

293+
ws?.onConnect = {[weak self] in
294+
guard let this = self else { return }
295+
296+
this.websocketDidConnect()
297+
}
298+
299+
ws?.onDisconnect = {[weak self] error in
300+
guard let this = self else { return }
301+
302+
this.websocketDidDisconnect(error: error)
303+
}
304+
305+
ws?.onData = {[weak self] data in
306+
guard let this = self else { return }
307+
308+
this.parseEngineData(data)
309+
}
310+
311+
ws?.onText = {[weak self] message in
312+
guard let this = self else { return }
313+
314+
this.parseEngineMessage(message)
315+
}
316+
295317
ws?.connect()
296318
}
297319

@@ -461,8 +483,6 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
461483
/// Parses a raw engine.io packet.
462484
///
463485
/// - parameter message: The message to parse.
464-
/// - parameter fromPolling: Whether this message is from long-polling.
465-
/// If `true` we might have to fix utf8 encoding.
466486
public func parseEngineMessage(_ message: String) {
467487
DefaultSocketLogger.Logger.log("Got message: \(message)", type: SocketEngine.logType)
468488

@@ -586,8 +606,8 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
586606
/// Writes a message to engine.io, independent of transport.
587607
///
588608
/// - parameter msg: The message to send.
589-
/// - parameter withType: The type of this message.
590-
/// - parameter withData: Any data that this message has.
609+
/// - parameter type: The type of this message.
610+
/// - parameter data: Any data that this message has.
591611
public func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data]) {
592612
engineQueue.async {
593613
guard self.connected else { return }
@@ -609,10 +629,9 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
609629
}
610630
}
611631

612-
// MARK: Starscream delegate conformance
632+
// WebSocket Methods
613633

614-
/// Delegate method for connection.
615-
public func websocketDidConnect(socket: WebSocketClient) {
634+
private func websocketDidConnect() {
616635
if !forceWebsockets {
617636
probing = true
618637
probeWebSocket()
@@ -623,8 +642,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
623642
}
624643
}
625644

626-
/// Delegate method for disconnection.
627-
public func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
645+
private func websocketDidDisconnect(error: Error?) {
628646
probing = false
629647

630648
if closed {

Source/SocketIO/Engine/SocketEngineSpec.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,13 @@ import Starscream
130130
/// Parses a raw engine.io packet.
131131
///
132132
/// - parameter message: The message to parse.
133-
/// - parameter fromPolling: Whether this message is from long-polling.
134-
/// If `true` we might have to fix utf8 encoding.
135133
func parseEngineMessage(_ message: String)
136134

137135
/// Writes a message to engine.io, independent of transport.
138136
///
139137
/// - parameter msg: The message to send.
140-
/// - parameter withType: The type of this message.
141-
/// - parameter withData: Any data that this message has.
138+
/// - parameter type: The type of this message.
139+
/// - parameter data: Any data that this message has.
142140
func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data])
143141
}
144142

Source/SocketIO/Engine/SocketEngineWebsocket.swift

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import Foundation
2727
import Starscream
2828

2929
/// Protocol that is used to implement socket.io WebSocket support
30-
public protocol SocketEngineWebsocket : SocketEngineSpec, WebSocketDelegate {
30+
public protocol SocketEngineWebsocket : SocketEngineSpec {
3131
// MARK: Methods
3232

3333
/// Sends an engine.io message through the WebSocket transport.
@@ -66,16 +66,4 @@ extension SocketEngineWebsocket {
6666
}
6767
}
6868
}
69-
70-
// MARK: Starscream delegate methods
71-
72-
/// Delegate method for when a message is received.
73-
public func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
74-
parseEngineMessage(text)
75-
}
76-
77-
/// Delegate method for when binary is received.
78-
public func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
79-
parseEngineData(data)
80-
}
8169
}

Source/SocketIO/Manager/SocketManager.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ open class SocketManager : NSObject, SocketManagerSpec, SocketParsable, SocketDa
241241
/// This will remove the socket for the manager's control, and make the socket instance useless and ready for
242242
/// releasing.
243243
///
244-
/// - parameter forNamespace: The namespace to disconnect from.
244+
/// - parameter nsp: The namespace to disconnect from.
245245
open func disconnectSocket(forNamespace nsp: String) {
246246
guard let socket = nsps.removeValue(forKey: nsp) else {
247247
DefaultSocketLogger.Logger.log("Could not find socket for \(nsp) to disconnect",
@@ -282,7 +282,7 @@ open class SocketManager : NSObject, SocketManagerSpec, SocketParsable, SocketDa
282282
/// Same as `emitAll(_:_:)`, but meant for Objective-C.
283283
///
284284
/// - parameter event: The event to send.
285-
/// - parameter withItems: The data to send with this event.
285+
/// - parameter items: The data to send with this event.
286286
open func emitAll(_ event: String, withItems items: [Any]) {
287287
forAll {socket in
288288
socket.emit(event, with: items)
@@ -508,7 +508,7 @@ open class SocketManager : NSObject, SocketManagerSpec, SocketParsable, SocketDa
508508
/// Call one of the `disconnectSocket` methods on this class to remove the socket from manager control.
509509
/// Or call `SocketIOClient.disconnect()` on the client.
510510
///
511-
/// - parameter forNamespace: The namespace for the socket.
511+
/// - parameter nsp: The namespace for the socket.
512512
/// - returns: A `SocketIOClient` for the given namespace.
513513
open func socket(forNamespace nsp: String) -> SocketIOClient {
514514
assert(nsp.hasPrefix("/"), "forNamespace must have a leading /")

Source/SocketIO/Manager/SocketManagerSpec.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ public protocol SocketManagerSpec : class, SocketEngineClient {
103103

104104
/// Disconnects the socket associated with `forNamespace`.
105105
///
106-
/// - parameter forNamespace: The namespace to disconnect from.
106+
/// - parameter nsp: The namespace to disconnect from.
107107
func disconnectSocket(forNamespace nsp: String)
108108

109109
/// Sends an event to the server on all namespaces in this manager.
110110
///
111111
/// - parameter event: The event to send.
112-
/// - parameter withItems: The data to send with this event.
112+
/// - parameter items: The data to send with this event.
113113
func emitAll(_ event: String, withItems items: [Any])
114114

115115
/// Tries to reconnect to the server.
@@ -133,7 +133,7 @@ public protocol SocketManagerSpec : class, SocketEngineClient {
133133
/// Call one of the `disconnectSocket` methods on the implementing class to remove the socket from manager control.
134134
/// Or call `SocketIOClient.disconnect()` on the client.
135135
///
136-
/// - parameter forNamespace: The namespace for the socket.
136+
/// - parameter nsp: The namespace for the socket.
137137
/// - returns: A `SocketIOClient` for the given namespace.
138138
func socket(forNamespace nsp: String) -> SocketIOClient
139139
}

Tests/TestSocketIO/SocketAckManagerTest.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class SocketAckManagerTest : XCTestCase {
2121
}
2222

2323
ackManager.addAck(1, callback: callback)
24-
ackManager.executeAck(1, with: itemsArray, onQueue: DispatchQueue.main)
24+
ackManager.executeAck(1, with: itemsArray)
2525

2626
waitForExpectations(timeout: 3.0, handler: nil)
2727
}
@@ -44,7 +44,7 @@ class SocketAckManagerTest : XCTestCase {
4444
}
4545

4646
ackManager.addAck(1, callback: callback)
47-
ackManager.timeoutAck(1, onQueue: DispatchQueue.main)
47+
ackManager.timeoutAck(1)
4848

4949
waitForExpectations(timeout: 0.2, handler: nil)
5050
}

Tests/TestSocketIO/SocketSideEffectTest.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ class SocketSideEffectTest: XCTestCase {
3838
waitForExpectations(timeout: 3, handler: nil)
3939
}
4040

41+
func testHandleAckWithAckEmit() {
42+
let expect = expectation(description: "handled ack")
43+
socket.emitWithAck("test").timingOut(after: 0) {data in
44+
XCTAssertEqual(data[0] as? String, "hello world")
45+
46+
self.socket.emitWithAck("test").timingOut(after: 0) {data in}
47+
expect.fulfill()
48+
}
49+
50+
manager.parseEngineMessage("30[\"hello world\"]")
51+
waitForExpectations(timeout: 3, handler: nil)
52+
}
53+
4154
func testHandleAck2() {
4255
let expect = expectation(description: "handled ack2")
4356
socket.emitWithAck("test").timingOut(after: 0) {data in

0 commit comments

Comments
 (0)