Skip to content

Commit f6ddfb2

Browse files
committed
Merge branch 'master' into feature/native-websockets
1 parent 98f0897 commit f6ddfb2

20 files changed

+391
-1826
lines changed

Cartfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
github "ashleymills/Reachability.swift" ~> 5.0.0
2-
github "daltoniam/Starscream" ~> 3.1.0
32
github "jedisct1/swift-sodium" == 0.8.0

Cartfile.resolved

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
github "ashleymills/Reachability.swift" "v5.0.0"
2-
github "daltoniam/Starscream" "3.1.1"
32
github "jedisct1/swift-sodium" "0.8.0"

PusherSwift.xcodeproj/project.pbxproj

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
539D9AFE2507F68400B5765A /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9AFD2507F68400B5765A /* Constants.swift */; };
3535
539D9AFF2507F69400B5765A /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9AFD2507F68400B5765A /* Constants.swift */; };
3636
539D9B002507F69B00B5765A /* PusherLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9AFB2507F67300B5765A /* PusherLogger.swift */; };
37+
539D9B022509101E00B5765A /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9B012509101E00B5765A /* WebSocket.swift */; };
38+
539D9B032509101E00B5765A /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9B012509101E00B5765A /* WebSocket.swift */; };
39+
539D9B05250913B300B5765A /* WebSocketConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9B04250913B300B5765A /* WebSocketConnection.swift */; };
40+
539D9B06250913B300B5765A /* WebSocketConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9B04250913B300B5765A /* WebSocketConnection.swift */; };
41+
539D9B082509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9B072509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift */; };
42+
539D9B092509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539D9B072509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift */; };
3743
736E53F5242A378B0052CC1B /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 736E53F3242A35D90052CC1B /* String+Extensions.swift */; };
3844
736E53F7242A45AC0052CC1B /* XCTest+Assertions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 736E53F6242A45AC0052CC1B /* XCTest+Assertions.swift */; };
3945
73D8A1E72435E5F3001FDE05 /* PusherDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33BA541F1D9035BD00CD853B /* PusherDelegate.swift */; };
@@ -141,6 +147,9 @@
141147
33C1FD6E1D81BFC300921AD7 /* ObjectiveC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectiveC.swift; sourceTree = "<group>"; };
142148
539D9AFB2507F67300B5765A /* PusherLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PusherLogger.swift; sourceTree = "<group>"; };
143149
539D9AFD2507F68400B5765A /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
150+
539D9B012509101E00B5765A /* WebSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebSocket.swift; sourceTree = "<group>"; };
151+
539D9B04250913B300B5765A /* WebSocketConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSocketConnection.swift; sourceTree = "<group>"; };
152+
539D9B072509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLSessionWebSocketTask.CloseCode+Extensions.swift"; sourceTree = "<group>"; };
144153
736E53F3242A35D90052CC1B /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
145154
736E53F6242A45AC0052CC1B /* XCTest+Assertions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTest+Assertions.swift"; sourceTree = "<group>"; };
146155
73D8A1FE2435E5F3001FDE05 /* PusherSwiftWithEncryption.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PusherSwiftWithEncryption.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -263,6 +272,7 @@
263272
3390D1E71F054D1E00E1944D /* Authorizer.swift */,
264273
3390D1E51F054D0400E1944D /* AuthRequestBuilderProtocol.swift */,
265274
33BA541F1D9035BD00CD853B /* PusherDelegate.swift */,
275+
539D9B04250913B300B5765A /* WebSocketConnection.swift */,
266276
);
267277
path = Protocols;
268278
sourceTree = "<group>";
@@ -278,6 +288,7 @@
278288
E2B21F06243F5B860049A35B /* PusherEvent.swift */,
279289
3389F5751CAEDE2800563F49 /* PusherGlobalChannel.swift */,
280290
3389F56D1CAEDDD800563F49 /* PusherPresenceChannel.swift */,
291+
539D9B012509101E00B5765A /* WebSocket.swift */,
281292
);
282293
path = Models;
283294
sourceTree = "<group>";
@@ -297,6 +308,7 @@
297308
5333ACFC24F80F5C006E8DF0 /* Extensions */ = {
298309
isa = PBXGroup;
299310
children = (
311+
539D9B072509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift */,
300312
E2B21F0C243F5DC10049A35B /* PusherWebsocketDelegate.swift */,
301313
);
302314
path = Extensions;
@@ -634,7 +646,6 @@
634646
files = (
635647
);
636648
inputPaths = (
637-
Starscream,
638649
Reachability,
639650
);
640651
name = "Copy Carthage Frameworks";
@@ -722,7 +733,6 @@
722733
files = (
723734
);
724735
inputPaths = (
725-
Starscream,
726736
Reachability,
727737
Sodium,
728738
);
@@ -743,6 +753,7 @@
743753
E26B8606244A079E00735172 /* PusherEncryptionHelpers.swift in Sources */,
744754
539D9AFE2507F68400B5765A /* Constants.swift in Sources */,
745755
E2B21F0A243F5BB50049A35B /* PusherConnection.swift in Sources */,
756+
539D9B05250913B300B5765A /* WebSocketConnection.swift in Sources */,
746757
33BA54201D9035BD00CD853B /* PusherDelegate.swift in Sources */,
747758
E2498293231E612700CFBBD6 /* PusherError.swift in Sources */,
748759
73D8A2282435F325001FDE05 /* PusherDecryptor.swift in Sources */,
@@ -753,13 +764,15 @@
753764
3389F5721CAEDDF300563F49 /* PusherChannels.swift in Sources */,
754765
E2CFE43122D79CA7004187C3 /* PusherParser.swift in Sources */,
755766
3389F5761CAEDE2800563F49 /* PusherGlobalChannel.swift in Sources */,
767+
539D9B022509101E00B5765A /* WebSocket.swift in Sources */,
756768
E2B21F01243F5B1E0049A35B /* PusherEventFactory.swift in Sources */,
757769
3389F57A1CAEDEC800563F49 /* PusherClientOptions.swift in Sources */,
758770
E2B21F07243F5B860049A35B /* PusherEvent.swift in Sources */,
759771
539D9AFC2507F67300B5765A /* PusherLogger.swift in Sources */,
760772
E2B21EFF243F5B1E0049A35B /* PusherEventQueue.swift in Sources */,
761773
3389F56E1CAEDDD800563F49 /* PusherPresenceChannel.swift in Sources */,
762774
33C1FD6F1D81BFC300921AD7 /* ObjectiveC.swift in Sources */,
775+
539D9B082509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift in Sources */,
763776
3390D1E61F054D0400E1944D /* AuthRequestBuilderProtocol.swift in Sources */,
764777
330D7A6A1CAEDA6C0032FF2C /* PusherSwift.swift in Sources */,
765778
);
@@ -797,6 +810,7 @@
797810
E26B8607244A079E00735172 /* PusherEncryptionHelpers.swift in Sources */,
798811
E2B21F0B243F5BB50049A35B /* PusherConnection.swift in Sources */,
799812
73D8A1E72435E5F3001FDE05 /* PusherDelegate.swift in Sources */,
813+
539D9B06250913B300B5765A /* WebSocketConnection.swift in Sources */,
800814
73D8A1E82435E5F3001FDE05 /* PusherError.swift in Sources */,
801815
73D8A2292435F329001FDE05 /* PusherDecryptor.swift in Sources */,
802816
73D8A1EB2435E5F3001FDE05 /* PusherCrypto.swift in Sources */,
@@ -807,13 +821,15 @@
807821
73D8A1EE2435E5F3001FDE05 /* PusherChannels.swift in Sources */,
808822
73D8A1EF2435E5F3001FDE05 /* PusherParser.swift in Sources */,
809823
539D9AFF2507F69400B5765A /* Constants.swift in Sources */,
824+
539D9B032509101E00B5765A /* WebSocket.swift in Sources */,
810825
73D8A1F02435E5F3001FDE05 /* PusherGlobalChannel.swift in Sources */,
811826
E2B21F02243F5B1E0049A35B /* PusherEventFactory.swift in Sources */,
812827
73D8A1F12435E5F3001FDE05 /* PusherClientOptions.swift in Sources */,
813828
E2B21F08243F5B860049A35B /* PusherEvent.swift in Sources */,
814829
E2B21F00243F5B1E0049A35B /* PusherEventQueue.swift in Sources */,
815830
73D8A1F22435E5F3001FDE05 /* PusherPresenceChannel.swift in Sources */,
816831
73D8A1F32435E5F3001FDE05 /* ObjectiveC.swift in Sources */,
832+
539D9B092509142200B5765A /* URLSessionWebSocketTask.CloseCode+Extensions.swift in Sources */,
817833
73D8A1F52435E5F3001FDE05 /* AuthRequestBuilderProtocol.swift in Sources */,
818834
73D8A1F62435E5F3001FDE05 /* PusherSwift.swift in Sources */,
819835
);
@@ -892,13 +908,13 @@
892908
GCC_WARN_UNINITIALIZED_AUTOS = YES;
893909
GCC_WARN_UNUSED_FUNCTION = YES;
894910
GCC_WARN_UNUSED_VARIABLE = YES;
895-
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
896-
MACOSX_DEPLOYMENT_TARGET = 10.11;
911+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
912+
MACOSX_DEPLOYMENT_TARGET = 10.15;
897913
ONLY_ACTIVE_ARCH = YES;
898914
SDKROOT = "";
899915
SUPPORTED_PLATFORMS = "macosx appletvos iphoneos appletvsimulator iphonesimulator";
900916
SWIFT_VERSION = 5.0;
901-
TVOS_DEPLOYMENT_TARGET = 9.0;
917+
TVOS_DEPLOYMENT_TARGET = 13.0;
902918
};
903919
name = Debug;
904920
};
@@ -932,13 +948,13 @@
932948
GCC_WARN_UNINITIALIZED_AUTOS = YES;
933949
GCC_WARN_UNUSED_FUNCTION = YES;
934950
GCC_WARN_UNUSED_VARIABLE = YES;
935-
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
936-
MACOSX_DEPLOYMENT_TARGET = 10.11;
951+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
952+
MACOSX_DEPLOYMENT_TARGET = 10.15;
937953
SDKROOT = "";
938954
SUPPORTED_PLATFORMS = "macosx appletvos iphoneos appletvsimulator iphonesimulator";
939955
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
940956
SWIFT_VERSION = 5.0;
941-
TVOS_DEPLOYMENT_TARGET = 9.0;
957+
TVOS_DEPLOYMENT_TARGET = 13.0;
942958
};
943959
name = Release;
944960
};

Sources/Extensions/PusherWebsocketDelegate.swift

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
import Foundation
2-
import Starscream
32

4-
extension PusherConnection: WebSocketDelegate {
3+
extension PusherConnection: WebSocketConnectionDelegate {
54

65
/**
76
Delegate method called when a message is received over a websocket
87

9-
- parameter ws: The websocket that has received the message
10-
- parameter text: The message received over the websocket
8+
- parameter connection: The websocket that has received the message
9+
- parameter string: The message received over the websocket
1110
*/
12-
public func websocketDidReceiveMessage(socket ws: WebSocketClient, text: String) {
13-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .receivedMessage, context: text))
11+
func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {
12+
self.delegate?.debugLog?(message: PusherLogger.debug(for: .receivedMessage, context: string))
1413

15-
guard let payload = PusherParser.getPusherEventJSON(from: text),
14+
guard let payload = PusherParser.getPusherEventJSON(from: string),
1615
let event = payload[Constants.JSONKeys.event] as? String
1716
else {
18-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .unableToHandleIncomingMessage, context: text))
17+
self.delegate?.debugLog?(message: PusherLogger.debug(for: .unableToHandleIncomingMessage, context: string))
1918
return
2019
}
2120

2221
if event == Constants.Events.Pusher.error {
2322
guard let error = PusherError(jsonObject: payload) else {
24-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .unableToHandleIncomingError, context: text))
23+
self.delegate?.debugLog?(message: PusherLogger.debug(for: .unableToHandleIncomingError,
24+
context: string))
2525
return
2626
}
2727
self.handleError(error: error)
@@ -30,13 +30,23 @@ extension PusherConnection: WebSocketDelegate {
3030
}
3131
}
3232

33-
/**
34-
Delegate method called when a websocket disconnected
33+
/// Delegate method called when a pong is received over a websocket
34+
/// - Parameter connection: The websocket that has received the pong
35+
func webSocketDidReceivePong(connection: WebSocketConnection) {
36+
self.delegate?.debugLog?(message: PusherLogger.debug(for: .pongReceived))
37+
resetActivityTimeoutTimer()
38+
}
3539

36-
- parameter ws: The websocket that disconnected
37-
- parameter error: The error, if one exists, when disconnected
38-
*/
39-
public func websocketDidDisconnect(socket ws: WebSocketClient, error: Error?) {
40+
/**
41+
Delegate method called when a websocket disconnected
42+
43+
- parameter connection: The websocket that disconnected
44+
- parameter closeCode: The closure code for the websocket connection.
45+
- parameter reason: Optional further information on the connection closure.
46+
*/
47+
func webSocketDidDisconnect(connection: WebSocketConnection,
48+
closeCode: Int,
49+
reason: Data?) {
4050
// Handles setting channel subscriptions to unsubscribed wheter disconnection
4151
// is intentional or not
4252
if connectionState == .disconnecting || connectionState == .connected {
@@ -55,14 +65,9 @@ extension PusherConnection: WebSocketDelegate {
5565
return
5666
}
5767

58-
// Handle error (if any)
68+
// Log the disconnection
5969

60-
if let error = error {
61-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .disconnectionWithError,
62-
context: "Error (code: \((error as NSError).code)): \(error.localizedDescription)"))
63-
} else {
64-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .disconnectionWithoutError))
65-
}
70+
self.delegate?.debugLog?(message: PusherLogger.debug(for: .disconnectionWithoutError))
6671

6772
// Attempt reconnect if possible
6873

@@ -126,20 +131,18 @@ extension PusherConnection: WebSocketDelegate {
126131
/**
127132
Delegate method called when a websocket connected
128133

129-
- parameter ws: The websocket that connected
134+
- parameter connection: The websocket that connected
130135
*/
131-
public func websocketDidConnect(socket ws: WebSocketClient) {
136+
func webSocketDidConnect(connection: WebSocketConnection) {
132137
self.socketConnected = true
133138
}
134139

135-
public func websocketDidReceiveData(socket ws: WebSocketClient, data: Data) {}
136-
}
137-
138-
extension PusherConnection: WebSocketPongDelegate {
139-
140-
public func websocketDidReceivePong(socket: WebSocketClient, data: Data?) {
141-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .pongReceived))
142-
resetActivityTimeoutTimer()
140+
func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {
141+
//
143142
}
144143

144+
func webSocketDidReceiveError(connection: WebSocketConnection, error: Error) {
145+
self.delegate?.debugLog?(message: PusherLogger.debug(for: .disconnectionWithError,
146+
context: "Error (code: \((error as NSError).code)): \(error.localizedDescription)"))
147+
}
145148
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import Foundation
2+
3+
internal extension URLSessionWebSocketTask.CloseCode {
4+
5+
// MARK: - Pusher Channels Protocol close codes
6+
7+
/// Describes closure codes as specified by the Pusher Channels Protocol
8+
///
9+
/// For reference: https://pusher.com/docs/channels/library_auth_reference/pusher-websockets-protocol#error-codes
10+
enum PusherChannelsProtocol: Int {
11+
12+
// 4000 - 4099
13+
case applicationOnlyAcceptsSSLConnections = 4000
14+
case applicationDoesNotExist = 4001
15+
case applicationDisabled = 4003
16+
case applicationIsOverConnectionQuota = 4004
17+
case pathNotFound = 4005
18+
case invalidVersionStringFormat = 4006
19+
case unsupportedProtocolVersion = 4007
20+
case noProtocolVersionSupplied = 4008
21+
case connectionIsUnauthorized = 4009
22+
23+
// 4100 - 4199
24+
case overCapacity = 4100
25+
26+
// 4200 - 4299
27+
case genericReconnectImmediately = 4200
28+
29+
/// Ping was sent to the client, but no reply was received
30+
case pongReplyNotReceived = 4201
31+
32+
/// Client has been inactive for a long time (currently 24 hours)
33+
/// and client does not support ping.
34+
case closedAfterInactivity = 4202
35+
36+
// 4300 - 4399
37+
case clientEventRejectedDueToRateLimit = 4300
38+
39+
var reconnectionStrategy: PusherChannelsReconnectionStrategy {
40+
return PusherChannelsReconnectionStrategy(rawValue: self.rawValue)
41+
}
42+
}
43+
44+
// MARK: - Pusher Channels Protocol reconnection strategies
45+
46+
/// Describes the reconnection strategy for a given `PusherChannelsProtocol` closure code.
47+
enum PusherChannelsReconnectionStrategy: Int {
48+
49+
/// Indicates an error resulting in the connection being closed by Pusher Channels,
50+
/// and that attempting to reconnect using the same parameters will not succeed.
51+
case doNotReconnectUnchanged
52+
53+
/// Indicates an error resulting in the connection being closed by Pusher Channels,
54+
/// and that the client may reconnect after 1s or more.
55+
case reconnectAfterBackingOff
56+
57+
/// Indicates an error resulting in the connection being closed by Pusher Channels,
58+
/// and that the client may reconnect immediately.
59+
case reconnectImmediately
60+
61+
/// Indicates any other type of error in the connection being closed by Pusher Channels,
62+
/// and the client may reconnect if appropriate.
63+
case reconnectIfAppropriate
64+
65+
/// Indicates that the reconnection strategy is unknown due to the closure code being
66+
/// outside of the expected range as specified by the Pusher Channels Protocol.
67+
case unknown
68+
69+
init(rawValue: Int) {
70+
switch rawValue {
71+
case 4000...4099:
72+
self = .doNotReconnectUnchanged
73+
case 4100...4199:
74+
self = .reconnectAfterBackingOff
75+
case 4200...4299:
76+
self = .reconnectImmediately
77+
case 4300...4399:
78+
self = .reconnectIfAppropriate
79+
default:
80+
self = .unknown
81+
}
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)