diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index ff7b1fd..cddaaf9 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -24,7 +24,7 @@ import Foundation -public final class SocketEngine: NSObject, WebSocketDelegate { +public final class SocketEngine: NSObject, WebSocketDelegate { private typealias Probe = (msg: String, type: PacketType, data: [NSData]?) private typealias ProbeWaitQueue = [Probe] @@ -350,8 +350,10 @@ public final class SocketEngine: NSObject, WebSocketDelegate { // We had packets waiting for send when we upgraded // Send them raw private func flushWaitingForPostToWebSocket() { - for msg in postWait { - ws?.writeString(msg) + if let ws = ws { + for msg in postWait { + ws.writeString(msg) + } } postWait.removeAll(keepCapacity: true) @@ -495,7 +497,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { var n = 0 var msg = "" - func testLength(length:String, inout n:Int) -> Bool { + func testLength(length: String, inout n: Int) -> Bool { if let num = Int(length) { n = num return false @@ -525,8 +527,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { if msg.characters.count != 0 { // Be sure to capture the value of the msg - dispatch_async(handleQueue) {[weak self, msg] in - self?.parseEngineMessage(msg, fromPolling: true) + dispatch_async(handleQueue) { + self.parseEngineMessage(msg, fromPolling: true) } } @@ -549,7 +551,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { let type = PacketType(str: (message["^(\\d)"].groups()?[1]) ?? "") ?? { self.checkIfMessageIsBase64Binary(message) - return PacketType.Noop + return .Noop }() switch type { @@ -608,12 +610,10 @@ public final class SocketEngine: NSObject, WebSocketDelegate { postWait.append(strMsg) - if let datas = datas { - for data in datas { - let (_, b64Data) = createBinaryDataForSend(data) + for data in datas ?? [] { + let (_, b64Data) = createBinaryDataForSend(data) - postWait.append(b64Data!) - } + postWait.append(b64Data!) } if !waitingForPost { @@ -629,26 +629,22 @@ public final class SocketEngine: NSObject, WebSocketDelegate { ws?.writeString("\(type.rawValue)\(str)") - if let datas = datas { - for data in datas { - let (data, _) = createBinaryDataForSend(data) - if data != nil { - ws?.writeData(data!) - } + for data in datas ?? [] { + let (data, _) = createBinaryDataForSend(data) + if data != nil { + ws?.writeData(data!) } } } // Starts the ping timer private func startPingTimer() { - guard pingInterval != nil else { - return - } + if let pingInterval = pingInterval { + pingTimer?.invalidate() + pingTimer = nil - pingTimer?.invalidate() - dispatch_async(dispatch_get_main_queue()) {[weak self] in - if let this = self { - this.pingTimer = NSTimer.scheduledTimerWithTimeInterval(this.pingInterval!, target: this, + dispatch_async(dispatch_get_main_queue()) { + self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(pingInterval, target: self, selector: Selector("sendPing"), userInfo: nil, repeats: true) } } @@ -672,16 +668,16 @@ public final class SocketEngine: NSObject, WebSocketDelegate { Write a message, independent of transport. */ public func write(msg: String, withType type: PacketType, withData data: [NSData]?) { - dispatch_async(emitQueue) {[weak self] in - if let this = self where this.connected { - if this.websocket { - Logger.log("Writing ws: %@ has data: %@", type: this.logType, args: msg, + dispatch_async(emitQueue) { + if self.connected { + if self.websocket { + Logger.log("Writing ws: %@ has data: %@", type: self.logType, args: msg, data == nil ? false : true) - this.sendWebSocketMessage(msg, withType: type, datas: data) + self.sendWebSocketMessage(msg, withType: type, datas: data) } else { - Logger.log("Writing poll: %@ has data: %@", type: this.logType, args: msg, + Logger.log("Writing poll: %@ has data: %@", type: self.logType, args: msg, data == nil ? false : true) - this.sendPollMessage(msg, withType: type, datas: data) + self.sendPollMessage(msg, withType: type, datas: data) } } } diff --git a/SocketIOClientSwift/SocketIOClient.swift b/SocketIOClientSwift/SocketIOClient.swift index 0a1d8bf..3b3fbf3 100644 --- a/SocketIOClientSwift/SocketIOClient.swift +++ b/SocketIOClientSwift/SocketIOClient.swift @@ -25,10 +25,11 @@ import Foundation public final class SocketIOClient: NSObject, SocketEngineClient { - public let emitQueue = dispatch_queue_create("emitQueue", DISPATCH_QUEUE_SERIAL) - public let handleQueue: dispatch_queue_t! + private let emitQueue = dispatch_queue_create("emitQueue", DISPATCH_QUEUE_SERIAL) + private let handleQueue: dispatch_queue_t! + public let socketURL: String - + public private(set) var engine: SocketEngine? public private(set) var secure = false public private(set) var status = SocketIOClientStatus.NotConnected @@ -49,10 +50,11 @@ public final class SocketIOClient: NSObject, SocketEngineClient { private var connectParams: [String: AnyObject]? private var reconnectTimer: NSTimer? - let reconnectAttempts: Int! - var ackHandlers = SocketAckManager() - var currentAck = -1 - var waitingData = [SocketPacket]() + private let reconnectAttempts: Int! + private var ackHandlers = SocketAckManager() + private var currentAck = -1 + + internal var waitingData = [SocketPacket]() /** Create a new SocketIOClient. opts can be omitted @@ -112,10 +114,13 @@ public final class SocketIOClient: NSObject, SocketEngineClient { engine?.close(fast: true) } - private func addEngine() { + private func addEngine() -> SocketEngine { Logger.log("Adding engine", type: logType) - - engine = SocketEngine(client: self, opts: opts) + + let newEngine = SocketEngine(client: self, opts: opts) + + engine = newEngine + return newEngine } private func clearReconnectTimer() { @@ -148,28 +153,30 @@ public final class SocketIOClient: NSObject, SocketEngineClient { */ public func connect(timeoutAfter timeoutAfter:Int, withTimeoutHandler handler:(() -> Void)?) { - guard status != SocketIOClientStatus.Connected else { + assert(timeoutAfter >= 0, "Invalid timeout: \(timeoutAfter)") + + guard status != .Connected else { return } - if status == SocketIOClientStatus.Closed { + + if status == .Closed { Logger.log("Warning! This socket was previously closed. This might be dangerous!", type: logType) } status = SocketIOClientStatus.Connecting - addEngine() - engine?.open(connectParams) + addEngine().open(connectParams) guard timeoutAfter != 0 else { return } let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeoutAfter) * Int64(NSEC_PER_SEC)) - - dispatch_after(time, dispatch_get_main_queue()) {[weak self] in - if let this = self where this.status != SocketIOClientStatus.Connected { - this.status = SocketIOClientStatus.Closed - this.engine?.close(fast: true) + + dispatch_after(time, dispatch_get_main_queue()) { + if self.status != .Connected { + self.status = .Closed + self.engine?.close(fast: true) handler?() } @@ -181,15 +188,15 @@ public final class SocketIOClient: NSObject, SocketEngineClient { if let this = self { this.ackHandlers.addAck(ack, callback: callback) - dispatch_async(this.emitQueue) {[weak this] in - this?._emit(items, ack: ack) + dispatch_async(this.emitQueue) { + this._emit(items, ack: ack) } if timeout != 0 { let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeout * NSEC_PER_SEC)) - dispatch_after(time, dispatch_get_main_queue()) {[weak this] in - this?.ackHandlers.timeoutAck(ack) + dispatch_after(time, dispatch_get_main_queue()) { + this.ackHandlers.timeoutAck(ack) } } } @@ -198,7 +205,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient { func didConnect() { Logger.log("Socket connected", type: logType) - status = SocketIOClientStatus.Connected + status = .Connected currentReconnectAttempt = 0 clearReconnectTimer() @@ -208,13 +215,13 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } func didDisconnect(reason: String) { - guard status != SocketIOClientStatus.Closed else { + guard status != .Closed else { return } Logger.log("Disconnected: %@", type: logType, args: reason) - status = SocketIOClientStatus.Closed + status = .Closed reconnects = false @@ -249,12 +256,12 @@ public final class SocketIOClient: NSObject, SocketEngineClient { Same as emit, but meant for Objective-C */ public func emit(event: String, withItems items: [AnyObject]) { - guard status == SocketIOClientStatus.Connected else { + guard status == .Connected else { return } - - dispatch_async(emitQueue) {[weak self] in - self?._emit([event] + items) + + dispatch_async(emitQueue) { + self._emit([event] + items) } } @@ -274,7 +281,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } private func _emit(data: [AnyObject], ack: Int? = nil) { - guard status == SocketIOClientStatus.Connected else { + guard status == .Connected else { return } @@ -283,7 +290,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient { Logger.log("Emitting: %@", type: logType, args: str) - if packet.type == SocketPacket.PacketType.BinaryEvent { + if packet.type == .BinaryEvent { engine?.send(str, withData: packet.binary) } else { engine?.send(str, withData: nil) @@ -292,17 +299,17 @@ public final class SocketIOClient: NSObject, SocketEngineClient { // If the server wants to know that the client received data func emitAck(ack: Int, withItems items: [AnyObject]) { - dispatch_async(emitQueue) {[weak self] in - if let this = self where this.status == SocketIOClientStatus.Connected { - let packet = SocketPacket.packetFromEmit(items, id: ack ?? -1, nsp: this.nsp, ack: true) + dispatch_async(emitQueue) { + if self.status == .Connected { + let packet = SocketPacket.packetFromEmit(items, id: ack ?? -1, nsp: self.nsp, ack: true) let str = packet.packetString - Logger.log("Emitting Ack: %@", type: this.logType, args: str) + Logger.log("Emitting Ack: %@", type: self.logType, args: str) if packet.type == SocketPacket.PacketType.BinaryAck { - this.engine?.send(str, withData: packet.binary) + self.engine?.send(str, withData: packet.binary) } else { - this.engine?.send(str, withData: nil) + self.engine?.send(str, withData: nil) } } @@ -312,10 +319,10 @@ public final class SocketIOClient: NSObject, SocketEngineClient { public func engineDidClose(reason: String) { waitingData.removeAll() - if status == SocketIOClientStatus.Closed || !reconnects { + if status == .Closed || !reconnects { didDisconnect(reason) - } else if status != SocketIOClientStatus.Reconnecting { - status = SocketIOClientStatus.Reconnecting + } else if status != .Reconnecting { + status = .Reconnecting handleEvent("reconnect", data: [reason], isInternalMessage: true) tryReconnect() } @@ -334,22 +341,21 @@ public final class SocketIOClient: NSObject, SocketEngineClient { */ public func handleEvent(event: String, data: [AnyObject]?, isInternalMessage: Bool, wantsAck ack: Int? = nil) { - guard status == SocketIOClientStatus.Connected || isInternalMessage else { + guard status == .Connected || isInternalMessage else { return } - // println("Should do event: \(event) with data: \(data)") Logger.log("Handling event: %@ with data: %@", type: logType, args: event, data ?? "") if anyHandler != nil { - dispatch_async(handleQueue) {[weak self] in - self?.anyHandler?(SocketAnyEvent(event: event, items: data)) + dispatch_async(handleQueue) { + self.anyHandler?(SocketAnyEvent(event: event, items: data)) } } for handler in handlers where handler.event == event { if let ack = ack { - dispatch_async(handleQueue) {[weak self] in + dispatch_async(handleQueue) { handler.executeCallback(data, withAck: ack, withSocket: self) } } else { @@ -395,7 +401,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient { public func off(event: String) { Logger.log("Removing handler for event: %@", type: logType, args: event) - handlers = ContiguousArray(handlers.filter {!($0.event == event)}) + handlers = ContiguousArray(handlers.filter { $0.event != event }) } /** @@ -441,18 +447,14 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } public func parseSocketMessage(msg: String) { - dispatch_async(handleQueue) {[weak self] in - if let this = self { - SocketParser.parseSocketMessage(msg, socket: this) - } + dispatch_async(handleQueue) { + SocketParser.parseSocketMessage(msg, socket: self) } } public func parseBinaryData(data: NSData) { - dispatch_async(handleQueue) {[weak self] in - if let this = self { - SocketParser.parseBinaryData(data, socket: this) - } + dispatch_async(handleQueue) { + SocketParser.parseBinaryData(data, socket: self) } } @@ -468,19 +470,17 @@ public final class SocketIOClient: NSObject, SocketEngineClient { if reconnectTimer == nil { Logger.log("Starting reconnect", type: logType) - status = SocketIOClientStatus.Reconnecting + status = .Reconnecting - dispatch_async(dispatch_get_main_queue()) {[weak self] in - if let this = self { - this.reconnectTimer = NSTimer.scheduledTimerWithTimeInterval(Double(this.reconnectWait), - target: this, selector: "_tryReconnect", userInfo: nil, repeats: true) - } + dispatch_async(dispatch_get_main_queue()) { + self.reconnectTimer = NSTimer.scheduledTimerWithTimeInterval(Double(self.reconnectWait), + target: self, selector: "_tryReconnect", userInfo: nil, repeats: true) } } } - + @objc private func _tryReconnect() { - if status == SocketIOClientStatus.Connected { + if status == .Connected { clearReconnectTimer() return diff --git a/SocketIOClientSwift/SocketPacket.swift b/SocketIOClientSwift/SocketPacket.swift index a10854a..12b975a 100644 --- a/SocketIOClientSwift/SocketPacket.swift +++ b/SocketIOClientSwift/SocketPacket.swift @@ -28,6 +28,8 @@ struct SocketPacket { private let placeholders: Int private var currentPlace = 0 + private static let logType = "SocketPacket" + let nsp: String let id: Int let type: PacketType @@ -113,7 +115,7 @@ struct SocketPacket { message += jsonString! as String + "," } catch { - print("Error creating JSON object in SocketPacket.completeMessage") + Logger.error("Error creating JSON object in SocketPacket.completeMessage", type: SocketPacket.logType) } } else if var str = arg as? String { str = str["\n"] ~= "\\\\n" diff --git a/SocketIOClientSwift/SwiftRegex.swift b/SocketIOClientSwift/SwiftRegex.swift index fb306aa..fcd7652 100644 --- a/SocketIOClientSwift/SwiftRegex.swift +++ b/SocketIOClientSwift/SwiftRegex.swift @@ -13,9 +13,9 @@ import Foundation -var swiftRegexCache = [String: NSRegularExpression]() +private var swiftRegexCache = [String: NSRegularExpression]() -public class SwiftRegex: NSObject, BooleanType { +internal class SwiftRegex: NSObject, BooleanType { var target:String var regex: NSRegularExpression @@ -36,17 +36,16 @@ public class SwiftRegex: NSObject, BooleanType { } super.init() } - - class func failure(message: String) { - print("SwiftRegex: "+message) - //assert(false,"SwiftRegex: failed") + + private static func failure(message: String) { + fatalError("SwiftRegex: \(message)") } - - final var targetRange: NSRange { + + private final var targetRange: NSRange { return NSRange(location: 0,length: target.utf16.count) } - final func substring(range: NSRange) -> String? { + private final func substring(range: NSRange) -> String? { if ( range.location != NSNotFound ) { return (target as NSString).substringWithRange(range) } else { @@ -54,24 +53,24 @@ public class SwiftRegex: NSObject, BooleanType { } } - public func doesMatch(options: NSMatchingOptions!) -> Bool { + func doesMatch(options: NSMatchingOptions!) -> Bool { return range(options).location != NSNotFound } - public func range(options: NSMatchingOptions) -> NSRange { + func range(options: NSMatchingOptions) -> NSRange { return regex.rangeOfFirstMatchInString(target as String, options: [], range: targetRange) } - public func match(options: NSMatchingOptions) -> String? { + func match(options: NSMatchingOptions) -> String? { return substring(range(options)) } - public func groups() -> [String]? { + func groups() -> [String]? { return groupsForMatch(regex.firstMatchInString(target as String, options: NSMatchingOptions.WithoutAnchoringBounds, range: targetRange)) } - func groupsForMatch(match: NSTextCheckingResult!) -> [String]? { + private func groupsForMatch(match: NSTextCheckingResult!) -> [String]? { if match != nil { var groups = [String]() for groupno in 0...regex.numberOfCaptureGroups { @@ -87,7 +86,7 @@ public class SwiftRegex: NSObject, BooleanType { } } - public subscript(groupno: Int) -> String? { + subscript(groupno: Int) -> String? { get { return groups()?[groupno] } @@ -116,19 +115,19 @@ public class SwiftRegex: NSObject, BooleanType { return matches } - public func ranges() -> [NSRange] { + func ranges() -> [NSRange] { return matchResults().map { $0.range } } - public func matches() -> [String] { + func matches() -> [String] { return matchResults().map( { self.substring($0.range)!}) } - public func allGroups() -> [[String]?] { + func allGroups() -> [[String]?] { return matchResults().map {self.groupsForMatch($0)} } - public func dictionary(options: NSMatchingOptions!) -> Dictionary { + func dictionary(options: NSMatchingOptions!) -> Dictionary { var out = Dictionary() for match in matchResults() { out[substring(match.rangeAtIndex(1))!] = substring(match.rangeAtIndex(2))! @@ -153,31 +152,31 @@ public class SwiftRegex: NSObject, BooleanType { return out as String } - public var boolValue: Bool { + var boolValue: Bool { return doesMatch(nil) } } extension String { - public subscript(pattern: String, options: NSRegularExpressionOptions) -> SwiftRegex { + subscript(pattern: String, options: NSRegularExpressionOptions) -> SwiftRegex { return SwiftRegex(target: self, pattern: pattern, options: options) } } extension String { - public subscript(pattern: String) -> SwiftRegex { + subscript(pattern: String) -> SwiftRegex { return SwiftRegex(target: self, pattern: pattern, options: nil) } } -public func ~= (left: SwiftRegex, right: String) -> String { +func ~= (left: SwiftRegex, right: String) -> String { return left.substituteMatches({match, stop in return left.regex.replacementStringForResult( match, inString: left.target as String, offset: 0, template: right ) }, options: []) } -public func ~= (left: SwiftRegex, right: [String]) -> String { +func ~= (left: SwiftRegex, right: [String]) -> String { var matchNumber = 0 return left.substituteMatches({match, stop -> String in @@ -190,7 +189,7 @@ public func ~= (left: SwiftRegex, right: [String]) -> String { }, options: []) } -public func ~= (left: SwiftRegex, right: (String) -> String) -> String { +func ~= (left: SwiftRegex, right: (String) -> String) -> String { // return right(left.substring(match.range)) return left.substituteMatches( {match, stop -> String in @@ -198,7 +197,7 @@ public func ~= (left: SwiftRegex, right: (String) -> String) -> String { }, options: []) } -public func ~= (left: SwiftRegex, right: ([String]?) -> String) -> String { +func ~= (left: SwiftRegex, right: ([String]?) -> String) -> String { return left.substituteMatches({match, stop -> String in return right(left.groupsForMatch(match)) }, options: []) diff --git a/SocketIOClientSwift/WebSocket.swift b/SocketIOClientSwift/WebSocket.swift index af05abb..016be75 100644 --- a/SocketIOClientSwift/WebSocket.swift +++ b/SocketIOClientSwift/WebSocket.swift @@ -378,21 +378,17 @@ public class WebSocket : NSObject, NSStreamDelegate { } if totalSize > 0 { if validateResponse(buffer, bufferLen: totalSize) { - dispatch_async(queue, { [weak self] in - guard let weakSelf = self else { - return - } - - weakSelf.connected = true - if let connectBlock = weakSelf.onConnect { + dispatch_async(queue, { + self.connected = true + if let connectBlock = self.onConnect { connectBlock() } - weakSelf.delegate?.websocketDidConnect(weakSelf) + self.delegate?.websocketDidConnect(self) }) totalSize += 1 //skip the last \n let restSize = bufferLen - totalSize if restSize > 0 { - processRawMessage((buffer+totalSize),bufferLen: restSize) + processRawMessage((buffer+totalSize), bufferLen: restSize) } return true } @@ -525,15 +521,9 @@ public class WebSocket : NSObject, NSStreamDelegate { data = NSData(bytes: UnsafePointer((buffer+offset)), length: Int(len)) } if receivedOpcode == OpCode.Pong.rawValue { - dispatch_async(queue, { [weak self] in - guard let weakSelf = self else { - return - } - - if let pongBlock = weakSelf.onPong { - pongBlock() - } - weakSelf.pongDelegate?.websocketDidReceivePong(weakSelf) + dispatch_async(queue, { + self.onPong?() + self.pongDelegate?.websocketDidReceivePong(self) }) let step = Int(offset+numericCast(len)) @@ -618,33 +608,24 @@ public class WebSocket : NSObject, NSStreamDelegate { dequeueWrite(data, code: OpCode.Pong) } else if response.code == .TextFrame { let str: NSString? = NSString(data: response.buffer!, encoding: NSUTF8StringEncoding) - if str == nil { + + if let str = str as String? { + dispatch_async(queue, { + self.onText?(str) + self.delegate?.websocketDidReceiveMessage(self, text: str) + }) + } else { writeError(CloseCode.Encoding.rawValue) return false } - dispatch_async(queue, { [weak self] in - guard let weakSelf = self else { - return - } - - if let textBlock = weakSelf.onText { - textBlock(str! as String) - } - weakSelf.delegate?.websocketDidReceiveMessage(weakSelf, text: str! as String) - }) } else if response.code == .BinaryFrame { let data = response.buffer! //local copy so it is perverse for writing - dispatch_async(queue, { [weak self] in - guard let weakSelf = self else { - return - } - - if let dataBlock = weakSelf.onData { - dataBlock(data) - } - weakSelf.delegate?.websocketDidReceiveData(weakSelf, data: data) - }) + dispatch_async(queue) { + self.onData?(data) + self.delegate?.websocketDidReceiveData(self, data: data) + } } + readStack.removeLast() return true } @@ -745,17 +726,12 @@ public class WebSocket : NSObject, NSStreamDelegate { ///used to preform the disconnect delegate private func doDisconnect(error: NSError?) { if !self.didDisconnect { - dispatch_async(queue, { [weak self] in - guard let weakSelf = self else { - return - } + dispatch_async(queue) { + self.didDisconnect = true - weakSelf.didDisconnect = true - if let disconnect = weakSelf.onDisconnect { - disconnect(error) - } - weakSelf.delegate?.websocketDidDisconnect(weakSelf, error: error) - }) + self.onDisconnect?(error) + self.delegate?.websocketDidDisconnect(self, error: error) + } } } @@ -774,7 +750,7 @@ public class WebSocket : NSObject, NSStreamDelegate { import Foundation import Security -public class SSLCert { +private class SSLCert { var certData: NSData? var key: SecKeyRef? @@ -785,7 +761,7 @@ public class SSLCert { :returns: a representation security object to be used with */ - public init(data: NSData) { + init(data: NSData) { self.certData = data } @@ -796,7 +772,7 @@ public class SSLCert { :returns: a representation security object to be used with */ - public init(key: SecKeyRef) { + init(key: SecKeyRef) { self.key = key } }