Make a bunch of things public. Fixes #803
This commit is contained in:
		
							parent
							
								
									486a89d407
								
							
						
					
					
						commit
						91eea96308
					
				@ -39,7 +39,13 @@ public final class SocketAckEmitter : NSObject {
 | 
			
		||||
        return ackNum != -1
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init(socket: SocketIOClient, ackNum: Int) {
 | 
			
		||||
    // MARK: Initializers
 | 
			
		||||
 | 
			
		||||
    /// Creates a new `SocketAckEmitter`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter socket: The socket for this emitter.
 | 
			
		||||
    /// - parameter ackNum: The ack number for this emitter.
 | 
			
		||||
    public init(socket: SocketIOClient, ackNum: Int) {
 | 
			
		||||
        self.socket = socket
 | 
			
		||||
        self.ackNum = ackNum
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -24,12 +24,27 @@
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
struct SocketEventHandler {
 | 
			
		||||
    let event: String
 | 
			
		||||
    let id: UUID
 | 
			
		||||
    let callback: NormalCallback
 | 
			
		||||
    
 | 
			
		||||
    func executeCallback(with items: [Any], withAck ack: Int, withSocket socket: SocketIOClient) {
 | 
			
		||||
/// A wrapper around a handler.
 | 
			
		||||
public struct SocketEventHandler {
 | 
			
		||||
    // MARK: Properties
 | 
			
		||||
 | 
			
		||||
    /// The event for this handler.
 | 
			
		||||
    public let event: String
 | 
			
		||||
 | 
			
		||||
    /// A unique identifier for this handler.
 | 
			
		||||
    public let id: UUID
 | 
			
		||||
 | 
			
		||||
    /// The actual handler function.
 | 
			
		||||
    public let callback: NormalCallback
 | 
			
		||||
 | 
			
		||||
    // MARK: Methods
 | 
			
		||||
 | 
			
		||||
    /// Causes this handler to be executed.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter with: The data that this handler should be called with.
 | 
			
		||||
    /// - parameter withAck: The ack number that this event expects. Pass -1 to say this event doesn't expect an ack.
 | 
			
		||||
    /// - parameter withSocket: The socket that is calling this event.
 | 
			
		||||
    public func executeCallback(with items: [Any], withAck ack: Int, withSocket socket: SocketIOClient) {
 | 
			
		||||
        callback(items, SocketAckEmitter(socket: socket, ackNum: ack))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,26 +35,6 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
 | 
			
		||||
    private static let logType = "SocketIOClient"
 | 
			
		||||
 | 
			
		||||
    /// The engine for this client.
 | 
			
		||||
    @objc
 | 
			
		||||
    public private(set) var engine: SocketEngineSpec?
 | 
			
		||||
 | 
			
		||||
    /// The status of this client.
 | 
			
		||||
    @objc
 | 
			
		||||
    public private(set) var status = SocketIOClientStatus.notConnected {
 | 
			
		||||
        didSet {
 | 
			
		||||
            switch status {
 | 
			
		||||
            case .connected:
 | 
			
		||||
                reconnecting = false
 | 
			
		||||
                currentReconnectAttempt = 0
 | 
			
		||||
            default:
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            handleClientEvent(.statusChange, data: [status])
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// If `true` then every time `connect` is called, a new engine will be created.
 | 
			
		||||
    @objc
 | 
			
		||||
    public var forceNew = false
 | 
			
		||||
@ -94,20 +74,46 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
    @objc
 | 
			
		||||
    public var socketURL: URL
 | 
			
		||||
 | 
			
		||||
    var ackHandlers = SocketAckManager()
 | 
			
		||||
 | 
			
		||||
    /// A list of packets that are waiting for binary data.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The way that socket.io works all data should be sent directly after each packet.
 | 
			
		||||
    /// So this should ideally be an array of one packet waiting for data.
 | 
			
		||||
    var waitingPackets = [SocketPacket]()
 | 
			
		||||
    ///
 | 
			
		||||
    /// **This should not be modified directly.**
 | 
			
		||||
    public var waitingPackets = [SocketPacket]()
 | 
			
		||||
 | 
			
		||||
    /// A handler that will be called on any event.
 | 
			
		||||
    public private(set) var anyHandler: ((SocketAnyEvent) -> ())?
 | 
			
		||||
 | 
			
		||||
    /// The engine for this client.
 | 
			
		||||
    @objc
 | 
			
		||||
    public private(set) var engine: SocketEngineSpec?
 | 
			
		||||
 | 
			
		||||
    /// The array of handlers for this socket.
 | 
			
		||||
    public private(set) var handlers = [SocketEventHandler]()
 | 
			
		||||
 | 
			
		||||
    /// The status of this client.
 | 
			
		||||
    @objc
 | 
			
		||||
    public private(set) var status = SocketIOClientStatus.notConnected {
 | 
			
		||||
        didSet {
 | 
			
		||||
            switch status {
 | 
			
		||||
            case .connected:
 | 
			
		||||
                reconnecting = false
 | 
			
		||||
                currentReconnectAttempt = 0
 | 
			
		||||
            default:
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            handleClientEvent(.statusChange, data: [status])
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var ackHandlers = SocketAckManager()
 | 
			
		||||
 | 
			
		||||
    private(set) var currentAck = -1
 | 
			
		||||
    private(set) var reconnectAttempts = -1
 | 
			
		||||
 | 
			
		||||
    private var anyHandler: ((SocketAnyEvent) -> ())?
 | 
			
		||||
    private var currentReconnectAttempt = 0
 | 
			
		||||
    private var handlers = [SocketEventHandler]()
 | 
			
		||||
    private var reconnecting = false
 | 
			
		||||
 | 
			
		||||
    // MARK: Initializers
 | 
			
		||||
@ -232,7 +238,9 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
 | 
			
		||||
    /// Called when the client connects to a namespace. If the client was created with a namespace upfront,
 | 
			
		||||
    /// then this is only called when the client connects to that namespace.
 | 
			
		||||
    func didConnect(toNamespace namespace: String) {
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter toNamespace: The namespace that was connected to.
 | 
			
		||||
    open func didConnect(toNamespace namespace: String) {
 | 
			
		||||
        DefaultSocketLogger.Logger.log("Socket connected", type: SocketIOClient.logType)
 | 
			
		||||
 | 
			
		||||
        status = .connected
 | 
			
		||||
@ -241,7 +249,9 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Called when the client has disconnected from socket.io.
 | 
			
		||||
    func didDisconnect(reason: String) {
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter reason: The reason for the disconnection.
 | 
			
		||||
    open func didDisconnect(reason: String) {
 | 
			
		||||
        guard status != .disconnected else { return }
 | 
			
		||||
 | 
			
		||||
        DefaultSocketLogger.Logger.log("Disconnected: \(reason)", type: SocketIOClient.logType)
 | 
			
		||||
@ -361,8 +371,13 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
        engine?.send(str, withData: packet.binary)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If the server wants to know that the client received data
 | 
			
		||||
    func emitAck(_ ack: Int, with items: [Any]) {
 | 
			
		||||
    /// Call when you wish to tell the server that you've received the event for `ack`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// **You shouldn't need to call this directly.** Instead use an `SocketAckEmitter` that comes in an event callback.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter ack: The ack number.
 | 
			
		||||
    /// - parameter with: The data for this ack.
 | 
			
		||||
    open func emitAck(_ ack: Int, with items: [Any]) {
 | 
			
		||||
        guard status == .connected else { return }
 | 
			
		||||
 | 
			
		||||
        let packet = SocketPacket.packetFromEmit(items, id: ack, nsp: nsp, ack: true)
 | 
			
		||||
@ -419,8 +434,12 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
        DefaultSocketLogger.Logger.log(reason, type: SocketIOClient.logType)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Called when the socket gets an ack for something it sent
 | 
			
		||||
    func handleAck(_ ack: Int, data: [Any]) {
 | 
			
		||||
    /// Called when socket.io has acked one of our emits. Causes the corresponding ack callback to be called.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter ack: The number for this ack.
 | 
			
		||||
    /// - parameter data: The data sent back with this ack.
 | 
			
		||||
    @objc
 | 
			
		||||
    open func handleAck(_ ack: Int, data: [Any]) {
 | 
			
		||||
        guard status == .connected else { return }
 | 
			
		||||
 | 
			
		||||
        DefaultSocketLogger.Logger.log("Handling ack: \(ack) with data: \(data)", type: SocketIOClient.logType)
 | 
			
		||||
@ -428,12 +447,12 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
        ackHandlers.executeAck(ack, with: data, onQueue: handleQueue)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Causes an event to be handled, and any event handlers for that event to be called.
 | 
			
		||||
    /// Called when we get an event from socket.io.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The event that is to be handled.
 | 
			
		||||
    /// - parameter data: the data associated with this event.
 | 
			
		||||
    /// - parameter isInternalMessage: If `true` event handlers for this event will be called regardless of status.
 | 
			
		||||
    /// - parameter withAck: The ack number for this event. May be left out.
 | 
			
		||||
    /// - parameter event: The name of the event.
 | 
			
		||||
    /// - parameter data: The data that was sent with this event.
 | 
			
		||||
    /// - parameter isInternalMessage: Whether this event was sent internally. If `true` it is always sent to handlers.
 | 
			
		||||
    /// - parameter withAck: If > 0 then this event expects to get an ack back from the client.
 | 
			
		||||
    @objc
 | 
			
		||||
    open func handleEvent(_ event: String, data: [Any], isInternalMessage: Bool, withAck ack: Int = -1) {
 | 
			
		||||
        guard status == .connected || isInternalMessage else { return }
 | 
			
		||||
@ -447,7 +466,11 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    func handleClientEvent(_ event: SocketClientEvent, data: [Any]) {
 | 
			
		||||
    /// Called on socket.io specific events.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The `SocketClientEvent`.
 | 
			
		||||
    /// - parameter data: The data for this event.
 | 
			
		||||
    open func handleClientEvent(_ event: SocketClientEvent, data: [Any]) {
 | 
			
		||||
        handleEvent(event.rawValue, data: data, isInternalMessage: true)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -615,6 +638,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Removes all handlers.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Can be used after disconnecting to break any potential remaining retain cycles.
 | 
			
		||||
    @objc
 | 
			
		||||
    open func removeAllHandlers() {
 | 
			
		||||
 | 
			
		||||
@ -23,41 +23,118 @@
 | 
			
		||||
//  THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
import Dispatch
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
/// Defines the interface for a SocketIOClient.
 | 
			
		||||
protocol SocketIOClientSpec : class {
 | 
			
		||||
public protocol SocketIOClientSpec : class {
 | 
			
		||||
    // MARK: Properties
 | 
			
		||||
 | 
			
		||||
    /// A handler that will be called on any event.
 | 
			
		||||
    var anyHandler: ((SocketAnyEvent) -> ())? { get }
 | 
			
		||||
 | 
			
		||||
    /// The queue that all interaction with the client must be on.
 | 
			
		||||
    var handleQueue: DispatchQueue { get set }
 | 
			
		||||
 | 
			
		||||
    /// The array of handlers for this socket.
 | 
			
		||||
    var handlers: [SocketEventHandler] { get }
 | 
			
		||||
 | 
			
		||||
    /// The namespace that this socket is currently connected to.
 | 
			
		||||
    ///
 | 
			
		||||
    /// **Must** start with a `/`.
 | 
			
		||||
    var nsp: String { get set }
 | 
			
		||||
 | 
			
		||||
    /// A list of packets that are waiting for binary data.
 | 
			
		||||
    /// The status of this client.
 | 
			
		||||
    var status: SocketIOClientStatus { get }
 | 
			
		||||
 | 
			
		||||
    // MARK: Methods
 | 
			
		||||
 | 
			
		||||
    /// Connect to the server. The same as calling `connect(timeoutAfter:withHandler:)` with a timeout of 0.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The way that socket.io works all data should be sent directly after each packet.
 | 
			
		||||
    /// So this should ideally be an array of one packet waiting for data.
 | 
			
		||||
    var waitingPackets: [SocketPacket] { get set }
 | 
			
		||||
    /// Only call after adding your event listeners, unless you know what you're doing.
 | 
			
		||||
    func connect()
 | 
			
		||||
 | 
			
		||||
    /// Connect to the server. If we aren't connected after `timeoutAfter` seconds, then `withHandler` is called.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Only call after adding your event listeners, unless you know what you're doing.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter timeoutAfter: The number of seconds after which if we are not connected we assume the connection
 | 
			
		||||
    ///                           has failed. Pass 0 to never timeout.
 | 
			
		||||
    /// - parameter withHandler: The handler to call when the client fails to connect.
 | 
			
		||||
    func connect(timeoutAfter: Double, withHandler handler: (() -> ())?)
 | 
			
		||||
 | 
			
		||||
    /// Called when the client connects to a namespace. If the client was created with a namespace upfront,
 | 
			
		||||
    /// then this is only called when the client connects to that namespace.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter toNamespace: The namespace that was connected to.
 | 
			
		||||
    func didConnect(toNamespace namespace: String)
 | 
			
		||||
 | 
			
		||||
    /// Called when the client has disconnected from socket.io.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter reason: The reason for the disconnection.
 | 
			
		||||
    func didDisconnect(reason: String)
 | 
			
		||||
 | 
			
		||||
    /// Called when the client encounters an error.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter reason: The reason for the disconnection.
 | 
			
		||||
    func didError(reason: String)
 | 
			
		||||
 | 
			
		||||
    /// Disconnects the socket.
 | 
			
		||||
    func disconnect()
 | 
			
		||||
 | 
			
		||||
    /// 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.
 | 
			
		||||
    func emit(_ event: String, _ items: SocketData...)
 | 
			
		||||
 | 
			
		||||
    /// Call when you wish to tell the server that you've received the event for `ack`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter ack: The ack number.
 | 
			
		||||
    /// - parameter with: The data for this ack.
 | 
			
		||||
    func emitAck(_ ack: Int, with items: [Any])
 | 
			
		||||
 | 
			
		||||
    /// 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.
 | 
			
		||||
    func emitWithAck(_ event: String, _ items: SocketData...) -> OnAckCallback
 | 
			
		||||
 | 
			
		||||
    /// Called when socket.io has acked one of our emits. Causes the corresponding ack callback to be called.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter ack: The number for this ack.
 | 
			
		||||
    /// - parameter data: The data sent back with this ack.
 | 
			
		||||
    func handleAck(_ ack: Int, data: [Any])
 | 
			
		||||
 | 
			
		||||
    /// Called when we get an event from socket.io.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The name of the event.
 | 
			
		||||
    /// - parameter data: The data that was sent with this event.
 | 
			
		||||
    /// - parameter isInternalMessage: Whether this event was sent internally. If `true` it is always sent to handlers.
 | 
			
		||||
    /// - parameter withAck: If > 0 then this event expects to get an ack back from the client.
 | 
			
		||||
    func handleEvent(_ event: String, data: [Any], isInternalMessage: Bool, withAck ack: Int)
 | 
			
		||||
 | 
			
		||||
    /// Called on socket.io events.
 | 
			
		||||
    /// Called on socket.io specific events.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The `SocketClientEvent`.
 | 
			
		||||
    /// - parameter data: The data for this event.
 | 
			
		||||
    func handleClientEvent(_ event: SocketClientEvent, data: [Any])
 | 
			
		||||
 | 
			
		||||
    /// Call when you wish to leave a namespace and return to the default namespace.
 | 
			
		||||
@ -69,11 +146,81 @@ protocol SocketIOClientSpec : class {
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter namespace: The namespace to join.
 | 
			
		||||
    func joinNamespace(_ namespace: String)
 | 
			
		||||
 | 
			
		||||
    /// Removes handler(s) for a client event.
 | 
			
		||||
    ///
 | 
			
		||||
    /// If you wish to remove a client event handler, call the `off(id:)` with the UUID received from its `on` call.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter clientEvent: The event to remove handlers for.
 | 
			
		||||
    func off(clientEvent event: SocketClientEvent)
 | 
			
		||||
 | 
			
		||||
    /// Removes handler(s) based on an event name.
 | 
			
		||||
    ///
 | 
			
		||||
    /// If you wish to remove a specific event, call the `off(id:)` with the UUID received from its `on` call.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The event to remove handlers for.
 | 
			
		||||
    func off(_ event: String)
 | 
			
		||||
 | 
			
		||||
    /// Removes a handler with the specified UUID gotten from an `on` or `once`
 | 
			
		||||
    ///
 | 
			
		||||
    /// If you want to remove all events for an event, call the off `off(_:)` method with the event name.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter id: The UUID of the handler you wish to remove.
 | 
			
		||||
    func off(id: UUID)
 | 
			
		||||
 | 
			
		||||
    /// Adds a handler for an event.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The event name for this handler.
 | 
			
		||||
    /// - parameter callback: The callback that will execute when this event is received.
 | 
			
		||||
    /// - returns: A unique id for the handler that can be used to remove it.
 | 
			
		||||
    func on(_ event: String, callback: @escaping NormalCallback) -> UUID
 | 
			
		||||
 | 
			
		||||
    /// Adds a handler for a client event.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example:
 | 
			
		||||
    ///
 | 
			
		||||
    /// ```swift
 | 
			
		||||
    /// socket.on(clientEvent: .connect) {data, ack in
 | 
			
		||||
    ///     ...
 | 
			
		||||
    /// }
 | 
			
		||||
    /// ```
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The event for this handler.
 | 
			
		||||
    /// - parameter callback: The callback that will execute when this event is received.
 | 
			
		||||
    /// - returns: A unique id for the handler that can be used to remove it.
 | 
			
		||||
    func on(clientEvent event: SocketClientEvent, callback: @escaping NormalCallback) -> UUID
 | 
			
		||||
 | 
			
		||||
    /// Adds a single-use handler for a client event.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter clientEvent: The event for this handler.
 | 
			
		||||
    /// - parameter callback: The callback that will execute when this event is received.
 | 
			
		||||
    /// - returns: A unique id for the handler that can be used to remove it.
 | 
			
		||||
    func once(clientEvent event: SocketClientEvent, callback: @escaping NormalCallback) -> UUID
 | 
			
		||||
 | 
			
		||||
    /// Adds a single-use handler for an event.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter event: The event name for this handler.
 | 
			
		||||
    /// - parameter callback: The callback that will execute when this event is received.
 | 
			
		||||
    /// - returns: A unique id for the handler that can be used to remove it.
 | 
			
		||||
    func once(_ event: String, callback: @escaping NormalCallback) -> UUID
 | 
			
		||||
 | 
			
		||||
    /// Adds a handler that will be called on every event.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter handler: The callback that will execute whenever an event is received.
 | 
			
		||||
    func onAny(_ handler: @escaping (SocketAnyEvent) -> ())
 | 
			
		||||
 | 
			
		||||
    /// Tries to reconnect to the server.
 | 
			
		||||
    func reconnect()
 | 
			
		||||
 | 
			
		||||
    /// Removes all handlers.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Can be used after disconnecting to break any potential remaining retain cycles.
 | 
			
		||||
    func removeAllHandlers()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extension SocketIOClientSpec {
 | 
			
		||||
public extension SocketIOClientSpec {
 | 
			
		||||
    /// Default implementation.
 | 
			
		||||
    func didError(reason: String) {
 | 
			
		||||
    public func didError(reason: String) {
 | 
			
		||||
        DefaultSocketLogger.Logger.error("\(reason)", type: "SocketIOClient")
 | 
			
		||||
 | 
			
		||||
        handleClientEvent(.error, data: [reason])
 | 
			
		||||
@ -82,6 +229,8 @@ extension SocketIOClientSpec {
 | 
			
		||||
 | 
			
		||||
/// The set of events that are generated by the client.
 | 
			
		||||
public enum SocketClientEvent : String {
 | 
			
		||||
    // MARK: Cases
 | 
			
		||||
 | 
			
		||||
    /// Emitted when the client connects. This is also called on a successful reconnection. A connect event gets one
 | 
			
		||||
    /// data item: the namespace that was connected to.
 | 
			
		||||
    ///
 | 
			
		||||
 | 
			
		||||
@ -25,22 +25,39 @@
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
struct SocketPacket {
 | 
			
		||||
    enum PacketType: Int {
 | 
			
		||||
/// A struct that represents a socket.io packet.
 | 
			
		||||
public struct SocketPacket : CustomStringConvertible {
 | 
			
		||||
    // MARK: PacketType enum
 | 
			
		||||
 | 
			
		||||
    /// The type of packets.
 | 
			
		||||
    public enum PacketType: Int {
 | 
			
		||||
        case connect, disconnect, event, ack, error, binaryEvent, binaryAck
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private let placeholders: Int
 | 
			
		||||
    // MARK: Properties
 | 
			
		||||
 | 
			
		||||
    private static let logType = "SocketPacket"
 | 
			
		||||
 | 
			
		||||
    let nsp: String
 | 
			
		||||
    let id: Int
 | 
			
		||||
    let type: PacketType
 | 
			
		||||
    /// The namespace for this packet.
 | 
			
		||||
    public let nsp: String
 | 
			
		||||
 | 
			
		||||
    var binary: [Data]
 | 
			
		||||
    var data: [Any]
 | 
			
		||||
    var args: [Any] {
 | 
			
		||||
    /// If > 0 then this packet is using acking.
 | 
			
		||||
    public let id: Int
 | 
			
		||||
 | 
			
		||||
    /// The type of this packet.
 | 
			
		||||
    public let type: PacketType
 | 
			
		||||
 | 
			
		||||
    /// An array of binary data for this packet.
 | 
			
		||||
    public internal(set) var binary: [Data]
 | 
			
		||||
 | 
			
		||||
    /// The data for this event.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Note: This includes all data inside of the socket.io packet payload array, which includes the event name for
 | 
			
		||||
    /// event type packets.
 | 
			
		||||
    public internal(set) var data: [Any]
 | 
			
		||||
 | 
			
		||||
    /// Returns the payload for this packet, minus the event name if this is an event or binaryEvent type packet.
 | 
			
		||||
    public var args: [Any] {
 | 
			
		||||
        if type == .event || type == .binaryEvent && data.count != 0 {
 | 
			
		||||
            return Array(data.dropFirst())
 | 
			
		||||
        } else {
 | 
			
		||||
@ -48,16 +65,21 @@ struct SocketPacket {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var description: String {
 | 
			
		||||
    private let placeholders: Int
 | 
			
		||||
 | 
			
		||||
    /// A string representation of this packet.
 | 
			
		||||
    public var description: String {
 | 
			
		||||
        return "SocketPacket {type: \(String(type.rawValue)); data: " +
 | 
			
		||||
            "\(String(describing: data)); id: \(id); placeholders: \(placeholders); nsp: \(nsp)}"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var event: String {
 | 
			
		||||
    /// The event name for this packet.
 | 
			
		||||
    public var event: String {
 | 
			
		||||
        return String(describing: data[0])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var packetString: String {
 | 
			
		||||
    /// A string representation of this packet.
 | 
			
		||||
    public var packetString: String {
 | 
			
		||||
        return createPacketString()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,19 @@
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
/// Defines that a type will be able to parse socket.io-protocol messages.
 | 
			
		||||
protocol SocketParsable {
 | 
			
		||||
public protocol SocketParsable : class {
 | 
			
		||||
    // MARK: Properties
 | 
			
		||||
 | 
			
		||||
    /// A list of packets that are waiting for binary data.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The way that socket.io works all data should be sent directly after each packet.
 | 
			
		||||
    /// So this should ideally be an array of one packet waiting for data.
 | 
			
		||||
    ///
 | 
			
		||||
    /// **This should not be modified directly.**
 | 
			
		||||
    var waitingPackets: [SocketPacket] { get set }
 | 
			
		||||
 | 
			
		||||
    // MARK: Methods
 | 
			
		||||
 | 
			
		||||
    /// Called when the engine has received some binary data that should be attached to a packet.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Packets binary data should be sent directly after the packet that expects it, so there's confusion over
 | 
			
		||||
@ -39,18 +51,28 @@ protocol SocketParsable {
 | 
			
		||||
    func parseSocketMessage(_ message: String)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum SocketParsableError : Error {
 | 
			
		||||
/// Errors that can be thrown during parsing.
 | 
			
		||||
public enum SocketParsableError : Error {
 | 
			
		||||
    // MARK: Cases
 | 
			
		||||
 | 
			
		||||
    /// Thrown when a packet received has an invalid data array, or is missing the data array.
 | 
			
		||||
    case invalidDataArray
 | 
			
		||||
 | 
			
		||||
    /// Thrown when an malformed packet is received.
 | 
			
		||||
    case invalidPacket
 | 
			
		||||
 | 
			
		||||
    /// Thrown when the parser receives an unknown packet type.
 | 
			
		||||
    case invalidPacketType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extension SocketParsable where Self: SocketIOClientSpec {
 | 
			
		||||
public extension SocketParsable where Self: SocketIOClientSpec {
 | 
			
		||||
    private func isCorrectNamespace(_ nsp: String) -> Bool {
 | 
			
		||||
        return nsp == self.nsp
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private func handleConnect(_ packetNamespace: String) {
 | 
			
		||||
        // If we connected with a namespace, check if we've joined the default namespace first, then switch to the
 | 
			
		||||
        // other namespace
 | 
			
		||||
        if packetNamespace == "/" && nsp != "/" {
 | 
			
		||||
            joinNamespace(nsp)
 | 
			
		||||
        } else {
 | 
			
		||||
@ -79,8 +101,11 @@ extension SocketParsable where Self: SocketIOClientSpec {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Parses a messsage from the engine, returning a complete SocketPacket or throwing.
 | 
			
		||||
    func parseString(_ message: String) throws -> SocketPacket {
 | 
			
		||||
    /// Parses a message from the engine, returning a complete SocketPacket or throwing.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter message: The message to parse.
 | 
			
		||||
    /// - returns: A completed packet, or throwing.
 | 
			
		||||
    internal func parseString(_ message: String) throws -> SocketPacket {
 | 
			
		||||
        var reader = SocketStringReader(message: message)
 | 
			
		||||
 | 
			
		||||
		guard let type = Int(reader.read(count: 1)).flatMap({ SocketPacket.PacketType(rawValue: $0) }) else {
 | 
			
		||||
@ -148,7 +173,7 @@ extension SocketParsable where Self: SocketIOClientSpec {
 | 
			
		||||
    /// Called when the engine has received a string that should be parsed into a socket.io packet.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter message: The string that needs parsing.
 | 
			
		||||
    func parseSocketMessage(_ message: String) {
 | 
			
		||||
    public func parseSocketMessage(_ message: String) {
 | 
			
		||||
        guard !message.isEmpty else { return }
 | 
			
		||||
 | 
			
		||||
        DefaultSocketLogger.Logger.log("Parsing \(message)", type: "SocketParser")
 | 
			
		||||
@ -171,7 +196,7 @@ extension SocketParsable where Self: SocketIOClientSpec {
 | 
			
		||||
    /// into the correct placeholder.
 | 
			
		||||
    ///
 | 
			
		||||
    /// - parameter data: The data that should be attached to a packet.
 | 
			
		||||
    func parseBinaryData(_ data: Data) {
 | 
			
		||||
    public func parseBinaryData(_ data: Data) {
 | 
			
		||||
        guard !waitingPackets.isEmpty else {
 | 
			
		||||
            DefaultSocketLogger.Logger.error("Got data when not remaking packet", type: "SocketParser")
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user