Skip to content

Commit cb54cc8

Browse files
author
Daniel Browne
committed
Merge branch 'master' into feature/321-guard-let
2 parents ba09d30 + 6551342 commit cb54cc8

20 files changed

+161
-134
lines changed

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased](https://github.com/pusher/pusher-websocket-swift/compare/9.1.0...HEAD)
7+
## [Unreleased](https://github.com/pusher/pusher-websocket-swift/compare/9.1.1...HEAD)
8+
9+
## [9.1.1](https://github.com/pusher/pusher-websocket-swift/compare/9.1.0...9.1.1) - 2020-12-15
10+
11+
### Fixed
12+
13+
- Resolved a race condition that could prevent automatic reconnection attempts in certain circumstances.
814

915
## [9.1.0](https://github.com/pusher/pusher-websocket-swift/compare/9.0.0...9.1.0) - 2020-12-07
1016

@@ -73,7 +79,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7379

7480
### Added
7581

76-
- Added new `bind` functions which accept a callback that receives a `PusherEvent`. A `PusherEvent` represents an event received from the websocket and has properties containing the event name, channel name and data. In addition, `PusherEvent` has a new property, `userId`, which allows you to verify the ID of the user who triggered a client event on a presence channel. You can read more about this feature in [the docs](https://pusher.com/docs/channels/using_channels/events#user-id-in-client-events). All the old `bind` functions are still available for backwards compatibility. The `data` property of `PusherEvent` is not automatically parsed from JSON and you can decide to parse that as required. The parsing behaviour is unchanged for data passed to callbacks bound by the old `bind` functions.
82+
- Added new `bind` functions which accept a callback that receives a `PusherEvent`. A `PusherEvent` represents an event received from the websocket and has properties containing the event name, channel name and data. In addition, `PusherEvent` has a new property, `userId`, which allows you to verify the ID of the user who triggered a client event on a presence channel. You can read more about this feature in [the docs](https://pusher.com/docs/channels/using_channels/events#user-id-in-client-events). All the old `bind` functions are still available for backwards compatibility. The `data` property of `PusherEvent` is not automatically parsed from JSON and you can decide to parse that as required. The parsing behavior is unchanged for data passed to callbacks bound by the old `bind` functions.
7783

7884
### Changed
7985

Cartfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
github "bitmark-inc/tweetnacl-swiftwrap" ~> 1.0
2-
github "pusher/NWWebSocket" ~> 0.5.0
2+
github "pusher/NWWebSocket" ~> 0.5.1

Cartfile.resolved

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
github "bitmark-inc/tweetnacl-swiftwrap" "1.0.2"
2-
github "pusher/NWWebSocket" "0.5.0"
2+
github "pusher/NWWebSocket" "0.5.1"

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let package = Package(
99
.library(name: "PusherSwift", targets: ["PusherSwift"])
1010
],
1111
dependencies: [
12-
.package(url: "https://github.com/pusher/NWWebSocket.git", .upToNextMajor(from: "0.5.0")),
12+
.package(url: "https://github.com/pusher/NWWebSocket.git", .upToNextMajor(from: "0.5.1")),
1313
.package(url: "https://github.com/bitmark-inc/tweetnacl-swiftwrap", .upToNextMajor(from: "1.0.0")),
1414
],
1515
targets: [

PusherSwift.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'PusherSwift'
3-
s.version = '9.1.0'
3+
s.version = '9.1.1'
44
s.summary = 'A Pusher client library in Swift'
55
s.homepage = 'https://github.com/pusher/pusher-websocket-swift'
66
s.license = 'MIT'
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
1313
s.source_files = ['Sources/**/*.swift']
1414

1515
s.dependency 'TweetNacl', '~> 1.0.0'
16-
s.dependency 'NWWebSocket', '~> 0.5.0'
16+
s.dependency 'NWWebSocket', '~> 0.5.1'
1717

1818
s.ios.deployment_target = '13.0'
1919
s.osx.deployment_target = '10.15'

PusherSwiftWithEncryption.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'PusherSwiftWithEncryption'
3-
s.version = '9.1.0'
3+
s.version = '9.1.1'
44
s.summary = 'A Pusher client library in Swift that supports encrypted channels'
55
s.homepage = 'https://github.com/pusher/pusher-websocket-swift'
66
s.license = 'MIT'
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
1313
s.source_files = ['Sources/**/*.swift']
1414

1515
s.dependency 'TweetNacl', '~> 1.0.0'
16-
s.dependency 'NWWebSocket', '~> 0.5.0'
16+
s.dependency 'NWWebSocket', '~> 0.5.1'
1717

1818
s.ios.deployment_target = '13.0'
1919
s.osx.deployment_target = '10.15'

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ let package = Package(
146146
targets: ["YourPackage"]),
147147
],
148148
dependencies: [
149-
.package(url: "https://github.com/pusher/pusher-websocket-swift.git", from: "9.1.0"),
149+
.package(url: "https://github.com/pusher/pusher-websocket-swift.git", from: "9.1.1"),
150150
],
151151
targets: [
152152
.target(
@@ -578,7 +578,7 @@ All of this is the case if you have the client option of `autoReconnect` set as
578578
579579
N.B: If the Pusher servers close the websocket with a [Channels Protocol closure code](https://pusher.com/docs/channels/library_auth_reference/pusher-websockets-protocol#connection-closure), then the `autoReconnect` option is ignored, and the reconnection strategy is determined by the specific closure code that was received.
580580
581-
There are a couple of properties on the connection (`PusherConnection`) that you can set that affect how the reconnection behaviour works. These are:
581+
There are a couple of properties on the connection (`PusherConnection`) that you can set that affect how the reconnection behavior works. These are:
582582
583583
- `public var reconnectAttemptsMax: Int? = 6` - if you set this to `nil` then there is no maximum number of reconnect attempts and so attempts will continue to be made with an exponential backoff (based on number of attempts), otherwise only as many attempts as this property's value will be made before the connection's state moves to `.disconnected`
584584
- `public var maxReconnectGapInSeconds: Double? = nil` - if you want to set a maximum length of time (in seconds) between reconnect attempts then set this property appropriately
@@ -804,7 +804,7 @@ let pusherAuth = PusherAuth(auth: yourAuthString, channelData: yourOptionalChann
804804
let chan = self.pusher.subscribe(channelName, auth: pusherAuth)
805805
```
806806

807-
This PusherAuth object can be initialised with just an auth (String) value if the subscription is to a private channel, or both an `auth (String)` and `channelData (String)` pair of values if the subscription is to a presence channel.
807+
This PusherAuth object can be initialized with just an auth (String) value if the subscription is to a private channel, or both an `auth (String)` and `channelData (String)` pair of values if the subscription is to a presence channel.
808808

809809
These `auth` and `channelData` values are the values that you received if the json object created by a call to pusher.authenticate(...) in one of our various server libraries.
810810

@@ -877,7 +877,7 @@ PusherChannel *chan = [pusher subscribeWithChannelName:@"my-channel"];
877877

878878
### Global events
879879

880-
You can attach behaviour to these events regardless of the channel the event is broadcast to.
880+
You can attach behavior to these events regardless of the channel the event is broadcast to.
881881

882882
#### Swift
883883

Sources/Extensions/PusherWebsocketDelegate.swift

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,20 @@ extension PusherConnection: WebSocketConnectionDelegate {
1111
- parameter string: The message received over the websocket
1212
*/
1313
public func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {
14-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .receivedMessage, context: string))
14+
PusherLogger.shared.debug(for: .receivedMessage, context: string)
1515

1616
guard let payload = PusherParser.getPusherEventJSON(from: string),
1717
let event = payload[Constants.JSONKeys.event] as? String
1818
else {
19-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .unableToHandleIncomingMessage, context: string))
19+
PusherLogger.shared.debug(for: .unableToHandleIncomingMessage,
20+
context: string)
2021
return
2122
}
2223

2324
if event == Constants.Events.Pusher.error {
2425
guard let error = PusherError(jsonObject: payload) else {
25-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .unableToHandleIncomingError,
26-
context: string))
26+
PusherLogger.shared.debug(for: .unableToHandleIncomingError,
27+
context: string)
2728
return
2829
}
2930
self.handleError(error: error)
@@ -35,7 +36,7 @@ extension PusherConnection: WebSocketConnectionDelegate {
3536
/// Delegate method called when a pong is received over a websocket
3637
/// - Parameter connection: The websocket that has received the pong
3738
public func webSocketDidReceivePong(connection: WebSocketConnection) {
38-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .pongReceived))
39+
PusherLogger.shared.debug(for: .pongReceived)
3940
resetActivityTimeoutTimer()
4041
}
4142

@@ -49,7 +50,7 @@ extension PusherConnection: WebSocketConnectionDelegate {
4950
public func webSocketDidDisconnect(connection: WebSocketConnection,
5051
closeCode: NWProtocolWebSocket.CloseCode,
5152
reason: Data?) {
52-
// Handles setting channel subscriptions to unsubscribed wheter disconnection
53+
// Handles setting channel subscriptions to unsubscribed whether disconnection
5354
// is intentional or not
5455
if connectionState == .disconnecting || connectionState == .connected {
5556
for (_, channel) in self.channels.channels {
@@ -63,7 +64,7 @@ extension PusherConnection: WebSocketConnectionDelegate {
6364
updateConnectionState(to: .disconnected)
6465

6566
guard !intentionalDisconnect else {
66-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .intentionalDisconnection))
67+
PusherLogger.shared.debug(for: .intentionalDisconnection)
6768
return
6869
}
6970

@@ -81,7 +82,7 @@ extension PusherConnection: WebSocketConnectionDelegate {
8182
}
8283

8384
guard reconnectAttemptsMax == nil || reconnectAttempts < reconnectAttemptsMax! else {
84-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .maxReconnectAttemptsLimitReached))
85+
PusherLogger.shared.debug(for: .maxReconnectAttemptsLimitReached)
8586
return
8687
}
8788

@@ -90,9 +91,9 @@ extension PusherConnection: WebSocketConnectionDelegate {
9091

9192
public func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {
9293
if isViable {
93-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .networkConnectionViable))
94+
PusherLogger.shared.debug(for: .networkConnectionViable)
9495
} else {
95-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .networkConnectionUnviable))
96+
PusherLogger.shared.debug(for: .networkConnectionUnviable)
9697
}
9798
}
9899

@@ -101,10 +102,10 @@ extension PusherConnection: WebSocketConnectionDelegate {
101102
case .success:
102103
updateConnectionState(to: .reconnecting)
103104
case .failure(let error):
104-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .errorReceived,
105-
context: """
105+
PusherLogger.shared.debug(for: .errorReceived,
106+
context: """
106107
Path migration error: \(error.debugDescription)
107-
"""))
108+
""")
108109
}
109110
}
110111

@@ -187,8 +188,8 @@ extension PusherConnection: WebSocketConnectionDelegate {
187188
context = "\(timeInterval) seconds " + context
188189
}
189190

190-
self.delegate?.debugLog?(message: PusherLogger.debug(for: loggingEvent,
191-
context: context))
191+
PusherLogger.shared.debug(for: loggingEvent,
192+
context: context)
192193
}
193194

194195
/// Logs the websocket disconnection event.
@@ -214,8 +215,8 @@ extension PusherConnection: WebSocketConnectionDelegate {
214215
closeMessage += " Reason: \(reasonString)."
215216
}
216217

217-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .disconnectionWithoutError,
218-
context: closeMessage))
218+
PusherLogger.shared.debug(for: .disconnectionWithoutError,
219+
context: closeMessage)
219220
}
220221

221222
/**
@@ -232,9 +233,9 @@ extension PusherConnection: WebSocketConnectionDelegate {
232233
}
233234

234235
public func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {
235-
self.delegate?.debugLog?(message: PusherLogger.debug(for: .errorReceived,
236-
context: """
236+
PusherLogger.shared.debug(for: .errorReceived,
237+
context: """
237238
Error: \(error.debugDescription)
238-
"""))
239+
""")
239240
}
240241
}

Sources/Helpers/PusherLogger.swift

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,39 @@ internal class PusherLogger {
1313
case presenceChannelSubscriptionAttemptWithoutChannelData =
1414
"Attempting to subscribe to presence channel but no channelData value provided"
1515
case subscriptionSucceededNoDataInPayload = "Subscription succeeded event received without data key in payload"
16+
case unableToSubscribeToChannel = "Unable to subscribe to channel:"
17+
case unableToAddMemberToChannel = "Unable to add member to channel"
18+
case unableToRemoveMemberFromChannel = "Unable to remove member from channel"
19+
case authInfoForCompletionHandlerIsNil = "Auth info passed to authorizer completionHandler was nil"
20+
case authenticationFailed = "Authentication failed. You may not be connected"
21+
case authValueOnSubscriptionNotSupported = """
22+
Passing an auth value to 'subscribe' is not supported for encrypted channels. \
23+
Event decryption will fail. You must use one of the following auth methods: \
24+
'endpoint', 'authRequestBuilder', 'authorizer'
25+
"""
1626

1727
// Events
1828

1929
case clientEventSent = "sendClientEvent"
2030
case eventSent = "sendEvent"
2131
case skippedEventAfterDecryptionFailure = "Skipping event that failed to decrypt on channel"
32+
case cannotSendClientEventForChannel = "You must be subscribed to a private or presence channel to send client events"
33+
case clientEventsNotSupported = "Client events are not supported on encrypted channels:"
34+
35+
// JSON parsing
36+
37+
case unableToParseStringAsJSON = "Unable to parse string as JSON:"
38+
39+
// Misc
40+
41+
case genericError = ""
2242

2343
// Network
2444

2545
case networkConnectionViable = "Network connection became viable"
2646
case networkConnectionUnviable = "Network connection became unviable"
2747

28-
// Websockets
48+
// WebSocket
2949

3050
case attemptReconnectionAfterWaiting = "Attempting to reconnect after waiting"
3151
case attemptReconnectionImmediately = "Attempting to reconnect immediately"
@@ -48,63 +68,62 @@ internal class PusherLogger {
4868
case error = "[PUSHER ERROR]"
4969
}
5070

71+
internal static let shared = PusherLogger()
72+
73+
internal weak var delegate: PusherDelegate?
74+
5175
// MARK: - Event logging
5276

53-
/// A debug message relating to a particular event of interest.
77+
/// Logs a debug message relating to a particular event of interest.
5478
/// - Parameters:
5579
/// - event: A particular `LoggingEvent` of interest.
5680
/// - context: Additional context for the message.
57-
/// - Returns: A `String` with information to log concerning the event.
58-
internal static func debug(for event: LoggingEvent,
59-
context: CustomStringConvertible? = nil) -> String {
60-
return message(for: event, level: .debug, context: context)
81+
internal func debug(for event: LoggingEvent,
82+
context: CustomStringConvertible? = nil) {
83+
message(for: event, level: .debug, context: context)
6184
}
6285

63-
/// An informational message relating to a particular event of interest.
86+
/// Logs an informational message relating to a particular event of interest.
6487
/// - Parameters:
6588
/// - event: A particular `LoggingEvent` of interest.
6689
/// - context: Additional context for the message.
67-
/// - Returns: A `String` with information to log concerning the event.
68-
internal static func info(for event: LoggingEvent,
69-
context: CustomStringConvertible? = nil) -> String {
70-
return message(for: event, level: .info, context: context)
90+
internal func info(for event: LoggingEvent,
91+
context: CustomStringConvertible? = nil) {
92+
message(for: event, level: .info, context: context)
7193
}
7294

73-
/// A warning message relating to a particular event of interest.
95+
/// Logs a warning message relating to a particular event of interest.
7496
/// - Parameters:
7597
/// - event: A particular `LoggingEvent` of interest.
7698
/// - context: Additional context for the message.
77-
/// - Returns: A `String` with information to log concerning the event.
78-
internal static func warning(for event: LoggingEvent,
79-
context: CustomStringConvertible? = nil) -> String {
80-
return message(for: event, level: .warning, context: context)
99+
internal func warning(for event: LoggingEvent,
100+
context: CustomStringConvertible? = nil) {
101+
message(for: event, level: .warning, context: context)
81102
}
82103

83-
/// An error message relating to a particular event of interest.
104+
/// Logs an error message relating to a particular event of interest.
84105
/// - Parameters:
85106
/// - event: A particular `LoggingEvent` of interest.
86107
/// - context: Additional context for the message.
87-
/// - Returns: A `String` with information to log concerning the event.
88-
internal static func error(for event: LoggingEvent,
89-
context: CustomStringConvertible? = nil) -> String {
90-
return message(for: event, level: .error, context: context)
108+
internal func error(for event: LoggingEvent,
109+
context: CustomStringConvertible? = nil) {
110+
message(for: event, level: .error, context: context)
91111
}
92112

93113
// MARK: - Private methods
94114

95-
/// An informational message relating to a particular event of interest.
115+
/// Logs an informational message relating to a particular event of interest.
96116
/// - Parameter event: A particular `LoggingEvent` of interest.
97117
/// - Parameter level: The `LoggingLevel` to set for the message.
98118
/// - Parameter context: Additional context for the message.
99-
/// - Returns: A `String` with information to log concerning the event.
100-
private static func message(for event: LoggingEvent,
101-
level: LoggingLevel,
102-
context: CustomStringConvertible? = nil) -> String {
119+
private func message(for event: LoggingEvent,
120+
level: LoggingLevel,
121+
context: CustomStringConvertible? = nil) {
103122
var message = "\(level.rawValue) \(event.rawValue)"
104123
if let context = context {
105124
message += " \(context)"
106125
}
107126

108-
return message
127+
self.delegate?.debugLog?(message: message)
109128
}
110129
}

0 commit comments

Comments
 (0)