Merge branch 'development'
* development: Add note about manager not being thread safe Make it clear that `handleQueue` should be serial remove some redundant connected checking get rid of internal emitAck method open engine Add raw view to ack emitter change access level to public for raw view rename SocketBinaryView Add rawEmitView. Implements #992 Add way to skip binary inspection. bump version Set reconnectAttempts in manager. Fixes #989
This commit is contained in:
commit
41af615428
@ -1,7 +1,7 @@
|
|||||||
language: objective-c
|
language: objective-c
|
||||||
xcode_project: Socket.IO-Client-Swift.xcodeproj # path to your xcodeproj folder
|
xcode_project: Socket.IO-Client-Swift.xcodeproj # path to your xcodeproj folder
|
||||||
xcode_scheme: SocketIO-Mac
|
xcode_scheme: SocketIO-Mac
|
||||||
osx_image: xcode9
|
osx_image: xcode9.2
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|||||||
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,3 +1,13 @@
|
|||||||
|
# v13.2.0
|
||||||
|
|
||||||
|
- Add ability to bypass Data inspection in emits. [#992]((https://github.com/socketio/socket.io-client-swift/issues/992))
|
||||||
|
- Allow `SocketEngine` to be subclassed
|
||||||
|
|
||||||
|
# v13.1.3
|
||||||
|
|
||||||
|
- Fix setting reconnectAttempts [#989]((https://github.com/socketio/socket.io-client-swift/issues/989))
|
||||||
|
|
||||||
|
|
||||||
# v13.1.2
|
# v13.1.2
|
||||||
|
|
||||||
- Fix [#950](https://github.com/socketio/socket.io-client-swift/issues/950)
|
- Fix [#950](https://github.com/socketio/socket.io-client-swift/issues/950)
|
||||||
|
|||||||
@ -1,15 +1,6 @@
|
|||||||
{
|
{
|
||||||
"object": {
|
"object": {
|
||||||
"pins": [
|
"pins": [
|
||||||
{
|
|
||||||
"package": "SSCZLib",
|
|
||||||
"repositoryURL": "https://github.com/daltoniam/zlib-spm.git",
|
|
||||||
"state": {
|
|
||||||
"branch": null,
|
|
||||||
"revision": "83ac8d719a2f3aa775dbdf116a57f56fb2c49abb",
|
|
||||||
"version": "1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"package": "SSCommonCrypto",
|
"package": "SSCommonCrypto",
|
||||||
"repositoryURL": "https://github.com/daltoniam/common-crypto-spm",
|
"repositoryURL": "https://github.com/daltoniam/common-crypto-spm",
|
||||||
@ -27,6 +18,15 @@
|
|||||||
"revision": "6cb1c474e09b0a3aa60bcdc7553b570336d6a61a",
|
"revision": "6cb1c474e09b0a3aa60bcdc7553b570336d6a61a",
|
||||||
"version": "3.0.3"
|
"version": "3.0.3"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "SSCZLib",
|
||||||
|
"repositoryURL": "https://github.com/daltoniam/zlib-spm.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "83ac8d719a2f3aa775dbdf116a57f56fb2c49abb",
|
||||||
|
"version": "1.1.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "Socket.IO-Client-Swift"
|
s.name = "Socket.IO-Client-Swift"
|
||||||
s.module_name = "SocketIO"
|
s.module_name = "SocketIO"
|
||||||
s.version = "13.1.2"
|
s.version = "13.1.3"
|
||||||
s.summary = "Socket.IO-client for iOS and OS X"
|
s.summary = "Socket.IO-client for iOS and OS X"
|
||||||
s.description = <<-DESC
|
s.description = <<-DESC
|
||||||
Socket.IO-client for iOS and OS X.
|
Socket.IO-client for iOS and OS X.
|
||||||
@ -18,7 +18,7 @@ Pod::Spec.new do |s|
|
|||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
s.source = {
|
s.source = {
|
||||||
:git => "https://github.com/socketio/socket.io-client-swift.git",
|
:git => "https://github.com/socketio/socket.io-client-swift.git",
|
||||||
:tag => 'v13.1.2',
|
:tag => 'v13.1.3',
|
||||||
:submodules => true
|
:submodules => true
|
||||||
}
|
}
|
||||||
s.pod_target_xcconfig = {
|
s.pod_target_xcconfig = {
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1C6572803D7E252A77A86E5F /* SocketManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C65763817782DFAC67BE05C /* SocketManager.swift */; };
|
1C6572803D7E252A77A86E5F /* SocketManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C65763817782DFAC67BE05C /* SocketManager.swift */; };
|
||||||
|
1C6573B22DC9423CDFC32F05 /* SocketRawView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C657533E849FC3E4342C602 /* SocketRawView.swift */; };
|
||||||
1C657FBB3F670261780FD72E /* SocketManagerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C6574AF9687A213814753E4 /* SocketManagerSpec.swift */; };
|
1C657FBB3F670261780FD72E /* SocketManagerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C6574AF9687A213814753E4 /* SocketManagerSpec.swift */; };
|
||||||
1C686BE21F869AFD007D8627 /* SocketIOClientConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C686BD21F869AF1007D8627 /* SocketIOClientConfigurationTest.swift */; };
|
1C686BE21F869AFD007D8627 /* SocketIOClientConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C686BD21F869AF1007D8627 /* SocketIOClientConfigurationTest.swift */; };
|
||||||
1C686BE31F869AFD007D8627 /* SocketEngineTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C686BD31F869AF1007D8627 /* SocketEngineTest.swift */; };
|
1C686BE31F869AFD007D8627 /* SocketEngineTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C686BD31F869AF1007D8627 /* SocketEngineTest.swift */; };
|
||||||
@ -61,6 +62,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
1C6574AF9687A213814753E4 /* SocketManagerSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketManagerSpec.swift; sourceTree = "<group>"; };
|
1C6574AF9687A213814753E4 /* SocketManagerSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketManagerSpec.swift; sourceTree = "<group>"; };
|
||||||
|
1C657533E849FC3E4342C602 /* SocketRawView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketRawView.swift; sourceTree = "<group>"; };
|
||||||
1C65763817782DFAC67BE05C /* SocketManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketManager.swift; sourceTree = "<group>"; };
|
1C65763817782DFAC67BE05C /* SocketManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketManager.swift; sourceTree = "<group>"; };
|
||||||
1C686BD21F869AF1007D8627 /* SocketIOClientConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketIOClientConfigurationTest.swift; sourceTree = "<group>"; };
|
1C686BD21F869AF1007D8627 /* SocketIOClientConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketIOClientConfigurationTest.swift; sourceTree = "<group>"; };
|
||||||
1C686BD31F869AF1007D8627 /* SocketEngineTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketEngineTest.swift; sourceTree = "<group>"; };
|
1C686BD31F869AF1007D8627 /* SocketEngineTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketEngineTest.swift; sourceTree = "<group>"; };
|
||||||
@ -300,6 +302,7 @@
|
|||||||
DD52B078DB0A3C3D1BB507CD /* SocketIOClientOption.swift */,
|
DD52B078DB0A3C3D1BB507CD /* SocketIOClientOption.swift */,
|
||||||
DD52B1D9BC4AE46D38D827DE /* SocketIOStatus.swift */,
|
DD52B1D9BC4AE46D38D827DE /* SocketIOStatus.swift */,
|
||||||
DD52B57FFEE8560CFFD793B3 /* SocketIOClientConfiguration.swift */,
|
DD52B57FFEE8560CFFD793B3 /* SocketIOClientConfiguration.swift */,
|
||||||
|
1C657533E849FC3E4342C602 /* SocketRawView.swift */,
|
||||||
);
|
);
|
||||||
name = Client;
|
name = Client;
|
||||||
path = Source/SocketIO/Client;
|
path = Source/SocketIO/Client;
|
||||||
@ -480,6 +483,7 @@
|
|||||||
DD52B9412F660F828B683422 /* SocketParsable.swift in Sources */,
|
DD52B9412F660F828B683422 /* SocketParsable.swift in Sources */,
|
||||||
1C6572803D7E252A77A86E5F /* SocketManager.swift in Sources */,
|
1C6572803D7E252A77A86E5F /* SocketManager.swift in Sources */,
|
||||||
1C657FBB3F670261780FD72E /* SocketManagerSpec.swift in Sources */,
|
1C657FBB3F670261780FD72E /* SocketManagerSpec.swift in Sources */,
|
||||||
|
1C6573B22DC9423CDFC32F05 /* SocketRawView.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -29,8 +29,20 @@ import Foundation
|
|||||||
///
|
///
|
||||||
/// **NOTE**: You should not store this beyond the life of the event handler.
|
/// **NOTE**: You should not store this beyond the life of the event handler.
|
||||||
public final class SocketAckEmitter : NSObject {
|
public final class SocketAckEmitter : NSObject {
|
||||||
let socket: SocketIOClient
|
private unowned let socket: SocketIOClient
|
||||||
let ackNum: Int
|
private let ackNum: Int
|
||||||
|
|
||||||
|
/// A view into this emitter where emits do not check for binary data.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// ack.rawEmitView.with(myObject)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// **NOTE**: It is not safe to hold on to this view beyond the life of the socket.
|
||||||
|
@objc
|
||||||
|
public private(set) lazy var rawEmitView = SocketRawAckView(socket: socket, ackNum: ackNum)
|
||||||
|
|
||||||
// MARK: Properties
|
// MARK: Properties
|
||||||
|
|
||||||
@ -91,13 +103,16 @@ public final class SocketAckEmitter : NSObject {
|
|||||||
/// ```
|
/// ```
|
||||||
public final class OnAckCallback : NSObject {
|
public final class OnAckCallback : NSObject {
|
||||||
private let ackNumber: Int
|
private let ackNumber: Int
|
||||||
|
private let binary: Bool
|
||||||
private let items: [Any]
|
private let items: [Any]
|
||||||
|
|
||||||
private weak var socket: SocketIOClient?
|
private weak var socket: SocketIOClient?
|
||||||
|
|
||||||
init(ackNumber: Int, items: [Any], socket: SocketIOClient) {
|
init(ackNumber: Int, items: [Any], socket: SocketIOClient, binary: Bool = true) {
|
||||||
self.ackNumber = ackNumber
|
self.ackNumber = ackNumber
|
||||||
self.items = items
|
self.items = items
|
||||||
self.socket = socket
|
self.socket = socket
|
||||||
|
self.binary = binary
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@ -116,7 +131,7 @@ public final class OnAckCallback : NSObject {
|
|||||||
guard let socket = self.socket, ackNumber != -1 else { return }
|
guard let socket = self.socket, ackNumber != -1 else { return }
|
||||||
|
|
||||||
socket.ackHandlers.addAck(ackNumber, callback: callback)
|
socket.ackHandlers.addAck(ackNumber, callback: callback)
|
||||||
socket.emit(items, ack: ackNumber)
|
socket.emit(items, ack: ackNumber, binary: binary)
|
||||||
|
|
||||||
guard seconds != 0 else { return }
|
guard seconds != 0 else { return }
|
||||||
|
|
||||||
|
|||||||
@ -67,6 +67,18 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
|
|||||||
@objc
|
@objc
|
||||||
public private(set) weak var manager: SocketManagerSpec?
|
public private(set) weak var manager: SocketManagerSpec?
|
||||||
|
|
||||||
|
/// A view into this socket where emits do not check for binary data.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// socket.rawEmitView.emit("myEvent", myObject)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// **NOTE**: It is not safe to hold on to this view beyond the life of the socket.
|
||||||
|
@objc
|
||||||
|
public private(set) lazy var rawEmitView = SocketRawView(socket: self)
|
||||||
|
|
||||||
/// The status of this client.
|
/// The status of this client.
|
||||||
@objc
|
@objc
|
||||||
public private(set) var status = SocketIOStatus.notConnected {
|
public private(set) var status = SocketIOStatus.notConnected {
|
||||||
@ -148,7 +160,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createOnAck(_ items: [Any]) -> OnAckCallback {
|
func createOnAck(_ items: [Any], binary: Bool = true) -> OnAckCallback {
|
||||||
currentAck += 1
|
currentAck += 1
|
||||||
|
|
||||||
return OnAckCallback(ackNumber: currentAck, items: items, socket: self)
|
return OnAckCallback(ackNumber: currentAck, items: items, socket: self)
|
||||||
@ -216,11 +228,6 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
|
|||||||
/// - parameter items: The items to send with this event. Send an empty array to send no data.
|
/// - parameter items: The items to send with this event. Send an empty array to send no data.
|
||||||
@objc
|
@objc
|
||||||
open func emit(_ event: String, with items: [Any]) {
|
open func emit(_ event: String, with items: [Any]) {
|
||||||
guard status == .connected else {
|
|
||||||
handleClientEvent(.error, data: ["Tried emitting \(event) when not connected"])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
emit([event] + items)
|
emit([event] + items)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,16 +284,16 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
|
|||||||
return createOnAck([event] + items)
|
return createOnAck([event] + items)
|
||||||
}
|
}
|
||||||
|
|
||||||
func emit(_ data: [Any], ack: Int? = nil) {
|
func emit(_ data: [Any], ack: Int? = nil, binary: Bool = true, isAck: Bool = false) {
|
||||||
guard status == .connected else {
|
guard status == .connected else {
|
||||||
handleClientEvent(.error, data: ["Tried emitting when not connected"])
|
handleClientEvent(.error, data: ["Tried emitting when not connected"])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let packet = SocketPacket.packetFromEmit(data, id: ack ?? -1, nsp: nsp, ack: false)
|
let packet = SocketPacket.packetFromEmit(data, id: ack ?? -1, nsp: nsp, ack: isAck, checkForBinary: binary)
|
||||||
let str = packet.packetString
|
let str = packet.packetString
|
||||||
|
|
||||||
DefaultSocketLogger.Logger.log("Emitting: \(str)", type: logType)
|
DefaultSocketLogger.Logger.log("Emitting: \(str), Ack: \(isAck)", type: logType)
|
||||||
|
|
||||||
manager?.engine?.send(str, withData: packet.binary)
|
manager?.engine?.send(str, withData: packet.binary)
|
||||||
}
|
}
|
||||||
@ -298,14 +305,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec {
|
|||||||
/// - parameter ack: The ack number.
|
/// - parameter ack: The ack number.
|
||||||
/// - parameter with: The data for this ack.
|
/// - parameter with: The data for this ack.
|
||||||
open func emitAck(_ ack: Int, with items: [Any]) {
|
open func emitAck(_ ack: Int, with items: [Any]) {
|
||||||
guard status == .connected else { return }
|
emit(items, ack: ack, binary: true, isAck: true)
|
||||||
|
|
||||||
let packet = SocketPacket.packetFromEmit(items, id: ack, nsp: nsp, ack: true)
|
|
||||||
let str = packet.packetString
|
|
||||||
|
|
||||||
DefaultSocketLogger.Logger.log("Emitting Ack: \(str)", type: logType)
|
|
||||||
|
|
||||||
manager?.engine?.send(str, withData: packet.binary)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when socket.io has acked one of our emits. Causes the corresponding ack callback to be called.
|
/// Called when socket.io has acked one of our emits. Causes the corresponding ack callback to be called.
|
||||||
|
|||||||
@ -55,6 +55,8 @@ public enum SocketIOClientOption : ClientOption {
|
|||||||
|
|
||||||
/// The queue that all interaction with the client should occur on. This is the queue that event handlers are
|
/// The queue that all interaction with the client should occur on. This is the queue that event handlers are
|
||||||
/// called on.
|
/// called on.
|
||||||
|
///
|
||||||
|
/// **This should be a serial queue! Concurrent queues are not supported and might cause crashes and races**.
|
||||||
case handleQueue(DispatchQueue)
|
case handleQueue(DispatchQueue)
|
||||||
|
|
||||||
/// If passed `true`, the client will log debug information. This should be turned off in production code.
|
/// If passed `true`, the client will log debug information. This should be turned off in production code.
|
||||||
|
|||||||
@ -43,6 +43,17 @@ public protocol SocketIOClientSpec : class {
|
|||||||
/// **Must** start with a `/`.
|
/// **Must** start with a `/`.
|
||||||
var nsp: String { get }
|
var nsp: String { get }
|
||||||
|
|
||||||
|
/// A view into this socket where emits do not check for binary data.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// socket.rawEmitView.emit("myEvent", myObject)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// **NOTE**: It is not safe to hold on to this view beyond the life of the socket.
|
||||||
|
var rawEmitView: SocketRawView { get }
|
||||||
|
|
||||||
/// The status of this client.
|
/// The status of this client.
|
||||||
var status: SocketIOStatus { get }
|
var status: SocketIOStatus { get }
|
||||||
|
|
||||||
|
|||||||
163
Source/SocketIO/Client/SocketRawView.swift
Normal file
163
Source/SocketIO/Client/SocketRawView.swift
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
//
|
||||||
|
// SocketRawView.swift
|
||||||
|
// Socket.IO-Client-Swift
|
||||||
|
//
|
||||||
|
// Created by Erik Little on 3/30/18.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Class that gives a backwards compatible way to cause an emit not to recursively check for Data objects.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// socket.rawEmitView.emit("myEvent", myObject)
|
||||||
|
/// ```
|
||||||
|
public final class SocketRawView : NSObject {
|
||||||
|
private unowned let socket: SocketIOClient
|
||||||
|
|
||||||
|
init(socket: SocketIOClient) {
|
||||||
|
self.socket = socket
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send an event to the server, with optional data items.
|
||||||
|
///
|
||||||
|
/// If an error occurs trying to transform `items` into their socket representation, a `SocketClientEvent.error`
|
||||||
|
/// will be emitted. The structure of the error data is `[eventName, items, theError]`
|
||||||
|
///
|
||||||
|
/// - parameter event: The event to send.
|
||||||
|
/// - parameter items: The items to send with this event. May be left out.
|
||||||
|
public func emit(_ event: String, _ items: SocketData...) {
|
||||||
|
do {
|
||||||
|
try emit(event, with: items.map({ try $0.socketRepresentation() }))
|
||||||
|
} catch let err {
|
||||||
|
DefaultSocketLogger.Logger.error("Error creating socketRepresentation for emit: \(event), \(items)",
|
||||||
|
type: "SocketIOClient")
|
||||||
|
|
||||||
|
socket.handleClientEvent(.error, data: [event, items, err])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Same as emit, but meant for Objective-C
|
||||||
|
///
|
||||||
|
/// - parameter event: The event to send.
|
||||||
|
/// - parameter items: The items to send with this event. Send an empty array to send no data.
|
||||||
|
@objc
|
||||||
|
public func emit(_ event: String, with items: [Any]) {
|
||||||
|
socket.emit([event] + items, binary: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends a message to the server, requesting an ack.
|
||||||
|
///
|
||||||
|
/// **NOTE**: It is up to the server send an ack back, just calling this method does not mean the server will ack.
|
||||||
|
/// Check that your server's api will ack the event being sent.
|
||||||
|
///
|
||||||
|
/// If an error occurs trying to transform `items` into their socket representation, a `SocketClientEvent.error`
|
||||||
|
/// will be emitted. The structure of the error data is `[eventName, items, theError]`
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// socket.emitWithAck("myEvent", 1).timingOut(after: 1) {data in
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// - parameter event: The event to send.
|
||||||
|
/// - parameter items: The items to send with this event. May be left out.
|
||||||
|
/// - returns: An `OnAckCallback`. You must call the `timingOut(after:)` method before the event will be sent.
|
||||||
|
public func emitWithAck(_ event: String, _ items: SocketData...) -> OnAckCallback {
|
||||||
|
do {
|
||||||
|
return emitWithAck(event, with: try items.map({ try $0.socketRepresentation() }))
|
||||||
|
} catch let err {
|
||||||
|
DefaultSocketLogger.Logger.error("Error creating socketRepresentation for emit: \(event), \(items)",
|
||||||
|
type: "SocketIOClient")
|
||||||
|
|
||||||
|
socket.handleClientEvent(.error, data: [event, items, err])
|
||||||
|
|
||||||
|
return OnAckCallback(ackNumber: -1, items: [], socket: socket)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Same as emitWithAck, but for Objective-C
|
||||||
|
///
|
||||||
|
/// **NOTE**: It is up to the server send an ack back, just calling this method does not mean the server will ack.
|
||||||
|
/// Check that your server's api will ack the event being sent.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// socket.emitWithAck("myEvent", with: [1]).timingOut(after: 1) {data in
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// - parameter event: The event to send.
|
||||||
|
/// - parameter items: The items to send with this event. Use `[]` to send nothing.
|
||||||
|
/// - returns: An `OnAckCallback`. You must call the `timingOut(after:)` method before the event will be sent.
|
||||||
|
@objc
|
||||||
|
public func emitWithAck(_ event: String, with items: [Any]) -> OnAckCallback {
|
||||||
|
return socket.createOnAck([event] + items, binary: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Class that gives a backwards compatible way to cause an emit not to recursively check for Data objects.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// ack.rawEmitView.with(myObject)
|
||||||
|
/// ```
|
||||||
|
public final class SocketRawAckView : NSObject {
|
||||||
|
private unowned let socket: SocketIOClient
|
||||||
|
private let ackNum: Int
|
||||||
|
|
||||||
|
init(socket: SocketIOClient, ackNum: Int) {
|
||||||
|
self.socket = socket
|
||||||
|
self.ackNum = ackNum
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call to ack receiving this event.
|
||||||
|
///
|
||||||
|
/// If an error occurs trying to transform `items` into their socket representation, a `SocketClientEvent.error`
|
||||||
|
/// will be emitted. The structure of the error data is `[ackNum, items, theError]`
|
||||||
|
///
|
||||||
|
/// - parameter items: A variable number of items to send when acking.
|
||||||
|
public func with(_ items: SocketData...) {
|
||||||
|
guard ackNum != -1 else { return }
|
||||||
|
|
||||||
|
do {
|
||||||
|
socket.emit(try items.map({ try $0.socketRepresentation() }), ack: ackNum, binary: false, isAck: true)
|
||||||
|
} catch let err {
|
||||||
|
socket.handleClientEvent(.error, data: [ackNum, items, err])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call to ack receiving this event.
|
||||||
|
///
|
||||||
|
/// - parameter items: An array of items to send when acking. Use `[]` to send nothing.
|
||||||
|
@objc
|
||||||
|
public func with(_ items: [Any]) {
|
||||||
|
guard ackNum != -1 else { return }
|
||||||
|
|
||||||
|
socket.emit(items, ack: ackNum, binary: false, isAck: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -28,8 +28,7 @@ import Starscream
|
|||||||
|
|
||||||
/// The class that handles the engine.io protocol and transports.
|
/// The class that handles the engine.io protocol and transports.
|
||||||
/// See `SocketEnginePollable` and `SocketEngineWebsocket` for transport specific methods.
|
/// See `SocketEnginePollable` and `SocketEngineWebsocket` for transport specific methods.
|
||||||
public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePollable, SocketEngineWebsocket,
|
open class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePollable, SocketEngineWebsocket, ConfigSettable {
|
||||||
ConfigSettable {
|
|
||||||
// MARK: Properties
|
// MARK: Properties
|
||||||
|
|
||||||
private static let logType = "SocketEngine"
|
private static let logType = "SocketEngine"
|
||||||
@ -164,7 +163,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
/// - parameter client: The client for this engine.
|
/// - parameter client: The client for this engine.
|
||||||
/// - parameter url: The url for this engine.
|
/// - parameter url: The url for this engine.
|
||||||
/// - parameter options: The options for this engine.
|
/// - parameter options: The options for this engine.
|
||||||
public convenience init(client: SocketEngineClient, url: URL, options: [String: Any]?) {
|
public required convenience init(client: SocketEngineClient, url: URL, options: [String: Any]?) {
|
||||||
self.init(client: client, url: url, config: options?.toSocketConfiguration() ?? [])
|
self.init(client: client, url: url, config: options?.toSocketConfiguration() ?? [])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +213,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Starts the connection to the server.
|
/// Starts the connection to the server.
|
||||||
public func connect() {
|
open func connect() {
|
||||||
engineQueue.async {
|
engineQueue.async {
|
||||||
self._connect()
|
self._connect()
|
||||||
}
|
}
|
||||||
@ -318,7 +317,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Called when an error happens during execution. Causes a disconnection.
|
/// Called when an error happens during execution. Causes a disconnection.
|
||||||
public func didError(reason: String) {
|
open func didError(reason: String) {
|
||||||
DefaultSocketLogger.Logger.error("\(reason)", type: SocketEngine.logType)
|
DefaultSocketLogger.Logger.error("\(reason)", type: SocketEngine.logType)
|
||||||
client?.engineDidError(reason: reason)
|
client?.engineDidError(reason: reason)
|
||||||
disconnect(reason: reason)
|
disconnect(reason: reason)
|
||||||
@ -327,7 +326,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
/// Disconnects from the server.
|
/// Disconnects from the server.
|
||||||
///
|
///
|
||||||
/// - parameter reason: The reason for the disconnection. This is communicated up to the client.
|
/// - parameter reason: The reason for the disconnection. This is communicated up to the client.
|
||||||
public func disconnect(reason: String) {
|
open func disconnect(reason: String) {
|
||||||
engineQueue.async {
|
engineQueue.async {
|
||||||
self._disconnect(reason: reason)
|
self._disconnect(reason: reason)
|
||||||
}
|
}
|
||||||
@ -359,7 +358,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
/// WebSocket mode.
|
/// WebSocket mode.
|
||||||
///
|
///
|
||||||
/// **You shouldn't call this directly**
|
/// **You shouldn't call this directly**
|
||||||
public func doFastUpgrade() {
|
open func doFastUpgrade() {
|
||||||
if waitingForPoll {
|
if waitingForPoll {
|
||||||
DefaultSocketLogger.Logger.error("Outstanding poll when switched to WebSockets," +
|
DefaultSocketLogger.Logger.error("Outstanding poll when switched to WebSockets," +
|
||||||
"we'll probably disconnect soon. You should report this.", type: SocketEngine.logType)
|
"we'll probably disconnect soon. You should report this.", type: SocketEngine.logType)
|
||||||
@ -392,7 +391,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
/// the engine is attempting to upgrade to WebSocket it does not do any POSTing.
|
/// the engine is attempting to upgrade to WebSocket it does not do any POSTing.
|
||||||
///
|
///
|
||||||
/// **You shouldn't call this directly**
|
/// **You shouldn't call this directly**
|
||||||
public func flushWaitingForPostToWebSocket() {
|
open func flushWaitingForPostToWebSocket() {
|
||||||
guard let ws = self.ws else { return }
|
guard let ws = self.ws else { return }
|
||||||
|
|
||||||
for msg in postWait {
|
for msg in postWait {
|
||||||
@ -474,7 +473,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
/// Parses raw binary received from engine.io.
|
/// Parses raw binary received from engine.io.
|
||||||
///
|
///
|
||||||
/// - parameter data: The data to parse.
|
/// - parameter data: The data to parse.
|
||||||
public func parseEngineData(_ data: Data) {
|
open func parseEngineData(_ data: Data) {
|
||||||
DefaultSocketLogger.Logger.log("Got binary data: \(data)", type: SocketEngine.logType)
|
DefaultSocketLogger.Logger.log("Got binary data: \(data)", type: SocketEngine.logType)
|
||||||
|
|
||||||
client?.parseEngineBinaryData(data.subdata(in: 1..<data.endIndex))
|
client?.parseEngineBinaryData(data.subdata(in: 1..<data.endIndex))
|
||||||
@ -483,7 +482,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
/// Parses a raw engine.io packet.
|
/// Parses a raw engine.io packet.
|
||||||
///
|
///
|
||||||
/// - parameter message: The message to parse.
|
/// - parameter message: The message to parse.
|
||||||
public func parseEngineMessage(_ message: String) {
|
open func parseEngineMessage(_ message: String) {
|
||||||
DefaultSocketLogger.Logger.log("Got message: \(message)", type: SocketEngine.logType)
|
DefaultSocketLogger.Logger.log("Got message: \(message)", type: SocketEngine.logType)
|
||||||
|
|
||||||
let reader = SocketStringReader(message: message)
|
let reader = SocketStringReader(message: message)
|
||||||
@ -608,7 +607,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
|||||||
/// - parameter msg: The message to send.
|
/// - parameter msg: The message to send.
|
||||||
/// - parameter type: The type of this message.
|
/// - parameter type: The type of this message.
|
||||||
/// - parameter data: Any data that this message has.
|
/// - parameter data: Any data that this message has.
|
||||||
public func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data]) {
|
open func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data]) {
|
||||||
engineQueue.async {
|
engineQueue.async {
|
||||||
guard self.connected else { return }
|
guard self.connected else { return }
|
||||||
guard !self.probing else {
|
guard !self.probing else {
|
||||||
|
|||||||
@ -43,6 +43,8 @@ import Foundation
|
|||||||
/// To disconnect a socket and remove it from the manager, either call `SocketIOClient.disconnect()` on the socket,
|
/// To disconnect a socket and remove it from the manager, either call `SocketIOClient.disconnect()` on the socket,
|
||||||
/// or call one of the `disconnectSocket` methods on this class.
|
/// or call one of the `disconnectSocket` methods on this class.
|
||||||
///
|
///
|
||||||
|
/// **NOTE**: The manager is not thread/queue safe, all interaction with the manager should be done on the `handleQueue`
|
||||||
|
///
|
||||||
open class SocketManager : NSObject, SocketManagerSpec, SocketParsable, SocketDataBufferable, ConfigSettable {
|
open class SocketManager : NSObject, SocketManagerSpec, SocketParsable, SocketDataBufferable, ConfigSettable {
|
||||||
private static let logType = "SocketManager"
|
private static let logType = "SocketManager"
|
||||||
|
|
||||||
@ -476,6 +478,8 @@ open class SocketManager : NSObject, SocketManagerSpec, SocketParsable, SocketDa
|
|||||||
self.handleQueue = queue
|
self.handleQueue = queue
|
||||||
case let .reconnects(reconnects):
|
case let .reconnects(reconnects):
|
||||||
self.reconnects = reconnects
|
self.reconnects = reconnects
|
||||||
|
case let .reconnectAttempts(attempts):
|
||||||
|
self.reconnectAttempts = attempts
|
||||||
case let .reconnectWait(wait):
|
case let .reconnectWait(wait):
|
||||||
reconnectWait = abs(wait)
|
reconnectWait = abs(wait)
|
||||||
case let .log(log):
|
case let .log(log):
|
||||||
|
|||||||
@ -200,11 +200,15 @@ extension SocketPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func packetFromEmit(_ items: [Any], id: Int, nsp: String, ack: Bool) -> SocketPacket {
|
static func packetFromEmit(_ items: [Any], id: Int, nsp: String, ack: Bool, checkForBinary: Bool = true) -> SocketPacket {
|
||||||
let (parsedData, binary) = deconstructData(items)
|
if checkForBinary {
|
||||||
|
let (parsedData, binary) = deconstructData(items)
|
||||||
|
|
||||||
return SocketPacket(type: findType(binary.count, ack: ack), data: parsedData, id: id, nsp: nsp,
|
return SocketPacket(type: findType(binary.count, ack: ack), data: parsedData, id: id, nsp: nsp,
|
||||||
binary: binary)
|
binary: binary)
|
||||||
|
} else {
|
||||||
|
return SocketPacket(type: findType(0, ack: ack), data: items, id: id, nsp: nsp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,13 +79,15 @@ class SocketMangerTest : XCTestCase {
|
|||||||
.handleQueue(queue),
|
.handleQueue(queue),
|
||||||
.forceNew(true),
|
.forceNew(true),
|
||||||
.reconnects(false),
|
.reconnects(false),
|
||||||
.reconnectWait(5)
|
.reconnectWait(5),
|
||||||
|
.reconnectAttempts(5)
|
||||||
])
|
])
|
||||||
|
|
||||||
XCTAssertEqual(manager.handleQueue, queue)
|
XCTAssertEqual(manager.handleQueue, queue)
|
||||||
XCTAssertTrue(manager.forceNew)
|
XCTAssertTrue(manager.forceNew)
|
||||||
XCTAssertFalse(manager.reconnects)
|
XCTAssertFalse(manager.reconnects)
|
||||||
XCTAssertEqual(manager.reconnectWait, 5)
|
XCTAssertEqual(manager.reconnectWait, 5)
|
||||||
|
XCTAssertEqual(manager.reconnectAttempts, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testManagerRemovesSocket() {
|
func testManagerRemovesSocket() {
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
- (void)testOnSyntax {
|
- (void)testOnSyntax {
|
||||||
[self.socket on:@"someCallback" callback:^(NSArray* data, SocketAckEmitter* ack) {
|
[self.socket on:@"someCallback" callback:^(NSArray* data, SocketAckEmitter* ack) {
|
||||||
[ack with:@[@1]];
|
[ack with:@[@1]];
|
||||||
|
[[ack rawEmitView] with:@[@"hello"]];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +67,10 @@
|
|||||||
[self.socket emit:@"testEmit" with:@[@YES]];
|
[self.socket emit:@"testEmit" with:@[@YES]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testRawEmitSyntax {
|
||||||
|
[[self.socket rawEmitView] emit:@"myEvent" with:@[@1]];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)testEmitWithAckSyntax {
|
- (void)testEmitWithAckSyntax {
|
||||||
[[self.socket emitWithAck:@"testAckEmit" with:@[@YES]] timingOutAfter:0 callback:^(NSArray* data) { }];
|
[[self.socket emitWithAck:@"testAckEmit" with:@[@YES]] timingOutAfter:0 callback:^(NSArray* data) { }];
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user