diff --git a/SocketIO-iOSTests/AbstractSocketTest.swift b/SocketIO-iOSTests/AbstractSocketTest.swift index 5f66991..e5b16d5 100644 --- a/SocketIO-iOSTests/AbstractSocketTest.swift +++ b/SocketIO-iOSTests/AbstractSocketTest.swift @@ -20,11 +20,12 @@ class AbstractSocketTest: XCTestCase { func openConnection() { let expection = self.expectationWithDescription("connect") + XCTAssertTrue(socket.status == SocketIOClientStatus.NotConnected) socket.on("connect") {data, ack in expection.fulfill() } socket.connect() - XCTAssertTrue(socket.connecting) + XCTAssertEqual(socket.status, SocketIOClientStatus.Connecting) waitForExpectationsWithTimeout(AbstractSocketTest.TEST_TIMEOUT, handler: nil) } @@ -33,10 +34,7 @@ class AbstractSocketTest: XCTestCase { } func checkConnectionStatus() { - XCTAssertTrue(socket.connected) - XCTAssertFalse(socket.connecting) - XCTAssertFalse(socket.reconnecting) - XCTAssertFalse(socket.closed) + XCTAssertEqual(socket.status, SocketIOClientStatus.Connected) XCTAssertFalse(socket.secure) } diff --git a/SocketIO-iOSTests/SocketTestCases.swift b/SocketIO-iOSTests/SocketTestCases.swift index e17718e..b090e7d 100644 --- a/SocketIO-iOSTests/SocketTestCases.swift +++ b/SocketIO-iOSTests/SocketTestCases.swift @@ -52,8 +52,8 @@ class SocketTestCases: NSObject { func didGetResult(result:NSArray?, ack:AckEmitter?) { if let array = result?.firstObject as? NSArray { XCTAssertEqual(array.count, 2) - XCTAssertEqual(array.firstObject! as! String, "test3") - XCTAssertEqual(array.lastObject! as! String, "test4") + XCTAssertEqual((array.firstObject! as! String), "test3") + XCTAssertEqual((array.lastObject! as! String), "test4") }else { XCTFail("Should have NSArray as result") } @@ -113,10 +113,10 @@ class SocketTestCases: NSObject { let testName = "testJSONWithBuffer" func didGetResult(result:NSArray?, ack:AckEmitter?) { if let json = result?.firstObject as? NSDictionary { - XCTAssertEqual(json.valueForKey("testString")! as! String, "test") - XCTAssertEqual(json.valueForKey("testNumber")! as! Int, 15) + XCTAssertEqual((json.valueForKey("testString")! as! String), "test") + XCTAssertEqual((json.valueForKey("testNumber")! as! Int), 15) XCTAssertEqual((json.valueForKey("testArray")! as! Array).count, 2) - XCTAssertEqual((json.valueForKey("testArray")! as! Array).last! as! Int, 1) + XCTAssertEqual(((json.valueForKey("testArray")! as! Array).last! as! Int), 1) let string = NSString(data: (json.valueForKey("testArray")! as! Array).first! as! NSData, encoding: NSUTF8StringEncoding)! XCTAssertEqual(string, "gakgakgak2") }else { @@ -132,11 +132,11 @@ class SocketTestCases: NSObject { let testName = "testJSON" func didGetResult(result:NSArray?, ack:AckEmitter?) { if let json = result?.firstObject as? NSDictionary { - XCTAssertEqual(json.valueForKey("testString")! as! String, "test") - XCTAssertEqual(json.valueForKey("testNumber")! as! Int, 15) + XCTAssertEqual((json.valueForKey("testString")! as! String), "test") + XCTAssertEqual(json.valueForKey("testNumber")! as? Int, 15) XCTAssertEqual((json.valueForKey("testArray")! as! Array).count, 2) - XCTAssertEqual((json.valueForKey("testArray")! as! Array).first! as! Int, 1) - XCTAssertEqual((json.valueForKey("testArray")! as! Array).last! as! Int, 1) + XCTAssertEqual((json.valueForKey("testArray")! as! Array).first! as? Int, 1) + XCTAssertEqual((json.valueForKey("testArray")! as! Array).last! as? Int, 1) }else { XCTFail("Should have NSDictionary as result") @@ -168,13 +168,13 @@ class SocketTestCases: NSObject { return } if let array = result?.firstObject as? Array { - XCTAssertEqual(array.last! as! Int, 2) - XCTAssertEqual(array.first! as! Int, 1) + XCTAssertEqual((array.last! as! Int), 2) + XCTAssertEqual((array.first! as! Int), 1) }else { XCTFail("Should have Array as result") } if let dict = result?[1] as? NSDictionary { - XCTAssertEqual(dict.valueForKey("test") as! String, "bob") + XCTAssertEqual((dict.valueForKey("test") as! String), "bob") }else { XCTFail("Should have NSDictionary as result") @@ -212,13 +212,13 @@ class SocketTestCases: NSObject { return } if let array = result?.firstObject as? Array { - XCTAssertEqual(array.last! as! Int, 2) - XCTAssertEqual(array.first! as! Int, 1) + XCTAssertEqual((array.last! as! Int), 2) + XCTAssertEqual((array.first! as! Int), 1) }else { XCTFail("Should have Array as result") } if let dict = result?[1] as? NSDictionary { - XCTAssertEqual(dict.valueForKey("test") as! String, "bob") + XCTAssertEqual((dict.valueForKey("test") as! String), "bob") }else { XCTFail("Should have NSDictionary as result") diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index 92e873c..a375844 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -325,8 +325,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { let req = NSMutableURLRequest(URL: NSURL(string: urlPolling! + "&sid=\(sid)")!) - if cookies != nil { - let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) + if let cookies = cookies { + let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies) req.allHTTPHeaderFields = headers } @@ -375,8 +375,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { } private func handleClose() { - if polling { - client?.engineDidClose("Disconnect") + if let client = client where polling == true { + client.engineDidClose("Disconnect") } } @@ -494,8 +494,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { reqPolling.allHTTPHeaderFields = headers } - if extraHeaders != nil { - for (headerName, value) in extraHeaders! { + if let extraHeaders = extraHeaders { + for (headerName, value) in extraHeaders { reqPolling.setValue(value, forHTTPHeaderField: headerName) } } @@ -504,11 +504,10 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { } // Translatation of engine.io-parser#decodePayload - private func parsePollingMessage(str: String) { - if str.characters.count == 1 { + private func parsePollingMessage(str:String) { + guard str.characters.count != 1 else { return } - // println(str) let strArray = Array(str.characters) @@ -633,8 +632,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { postWait.append(strMsg) - if datas != nil { - for data in datas! { + if let datas = datas { + for data in datas { let (_, b64Data) = createBinaryDataForSend(data) postWait.append(b64Data!) @@ -654,8 +653,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { ws?.writeString("\(type.rawValue)\(str)") - if datas != nil { - for data in datas! { + if let datas = datas { + for data in datas { let (data, _) = createBinaryDataForSend(data) if data != nil { ws?.writeData(data!) @@ -666,7 +665,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { // Starts the ping timer private func startPingTimer() { - if pingInterval == nil { + guard pingInterval != nil else { return } @@ -719,8 +718,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { if let pType = PacketType(rawValue: type) { var arr = [NSData]() - if data != nil { - for d in data! { + if let data = data { + for d in data { arr.append(d as! NSData) } } diff --git a/SocketIOClientSwift/SocketIOClient.swift b/SocketIOClientSwift/SocketIOClient.swift index 3c84ffd..218d900 100644 --- a/SocketIOClientSwift/SocketIOClient.swift +++ b/SocketIOClientSwift/SocketIOClient.swift @@ -26,14 +26,11 @@ import Foundation public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient { private var anyHandler:((SocketAnyEvent) -> Void)? - private var _closed = false - private var _connected = false - private var _connecting = false + public private(set) var status = SocketIOClientStatus.NotConnected private var currentReconnectAttempt = 0 private var handlers = ContiguousArray() + public private(set) var secure = false private var connectParams: [String: AnyObject]? - private var _secure = false - private var _reconnecting = false private var reconnectTimer: NSTimer? let reconnectAttempts: Int! @@ -47,27 +44,13 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient public let handleAckQueue = dispatch_queue_create("handleAckQueue", DISPATCH_QUEUE_SERIAL) public let handleQueue: dispatch_queue_t! public let emitQueue = dispatch_queue_create("emitQueue", DISPATCH_QUEUE_SERIAL) - public var closed: Bool { - return _closed - } - public var connected: Bool { - return _connected - } - public var connecting: Bool { - return _connecting - } + public var engine:SocketEngine? public var nsp = "/" public var opts: [String: AnyObject]? public var reconnects = true - public var reconnecting: Bool { - return _reconnecting - } public var reconnectWait = 10 - public var secure: Bool { - return _secure - } - public var sid: String? { + public var sid:String? { return engine?.sid } @@ -76,7 +59,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient */ public init(var socketURL: String, opts: [String: AnyObject]? = nil) { if socketURL["https://"].matches().count != 0 { - self._secure = true + self.secure = true } socketURL = socketURL["http://"] ~= "" @@ -145,9 +128,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient SocketLogger.log("Closing socket", client: self) reconnects = false - _connecting = false - _connected = false - _reconnecting = false + status = SocketIOClientStatus.Closed engine?.close(fast: fast) engine = nil } @@ -162,28 +143,28 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient /** Connect to the server. If we aren't connected after timeoutAfter, call handler */ - public func connect(timeoutAfter timeoutAfter: Int, withTimeoutHandler handler: (() -> Void)?) { - if closed { - SocketLogger.log("Warning! This socket was previously closed. This might be dangerous!", client: self) - _closed = false - } else if connected { + public func connect(timeoutAfter timeoutAfter:Int, + withTimeoutHandler handler:(() -> Void)?) { + guard status != SocketIOClientStatus.Connected else { return } + if status == SocketIOClientStatus.Closed { + SocketLogger.log("Warning! This socket was previously closed. This might be dangerous!", client: self) + } - _connecting = true + status = SocketIOClientStatus.Connecting addEngine() engine?.open(connectParams) - if timeoutAfter == 0 { + 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.connected { - this._closed = true - this._connecting = false + if let this = self where this.status != SocketIOClientStatus.Connected { + this.status = SocketIOClientStatus.Closed this.engine?.close(fast: true) handler?() @@ -213,11 +194,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient func didConnect() { SocketLogger.log("Socket connected", client: self) - - _closed = false - _connected = true - _connecting = false - _reconnecting = false + status = SocketIOClientStatus.Connected currentReconnectAttempt = 0 clearReconnectTimer() @@ -226,18 +203,16 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient handleEvent("connect", data: nil, isInternalMessage: false) } - func didDisconnect(reason: String) { - if closed { + func didDisconnect(reason:String) { + guard status != SocketIOClientStatus.Closed else { return } SocketLogger.log("Disconnected: %@", client: self, args: reason) - _closed = true - _connected = false + status = SocketIOClientStatus.Closed + reconnects = false - _connecting = false - _reconnecting = false // Make sure the engine is actually dead. engine?.close(fast: true) @@ -262,21 +237,15 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient /** Send a message to the server */ - public func emit(event:String, _ items: AnyObject...) { - if !connected { - return - } - - dispatch_async(emitQueue) {[weak self] in - self?._emit(event, items) - } + public func emit(event:String, _ items:AnyObject...) { + emit(event, withItems: items) } /** Same as emit, but meant for Objective-C */ - public func emit(event: String, withItems items: [AnyObject]) { - if !connected { + public func emit(event:String, withItems items:[AnyObject]) { + guard status == SocketIOClientStatus.Connected else { return } @@ -289,27 +258,19 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient Sends a message to the server, requesting an ack. Use the onAck method of SocketAckHandler to add an ack. */ - public func emitWithAck(event: String, _ items: AnyObject...) -> OnAckCallback { - if !connected { - return createOnAck(event, items: items) - } - + public func emitWithAck(event:String, _ items:AnyObject...) -> OnAckCallback { return createOnAck(event, items: items) } /** Same as emitWithAck, but for Objective-C */ - public func emitWithAck(event: String, withItems items: [AnyObject]) -> OnAckCallback { - if !connected { - return createOnAck(event, items: items) - } - + public func emitWithAck(event:String, withItems items:[AnyObject]) -> OnAckCallback { return createOnAck(event, items: items) } - private func _emit(event: String, _ args: [AnyObject], ack: Int? = nil) { - if !connected { + private func _emit(event:String, _ args:[AnyObject], ack:Int? = nil) { + guard status == SocketIOClientStatus.Connected else { return } @@ -328,7 +289,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient // If the server wants to know that the client received data func emitAck(ack: Int, withData args: [AnyObject]) { dispatch_async(emitQueue) {[weak self] in - if let this = self where this.connected { + if let this = self where this.status == SocketIOClientStatus.Connected { let packet = SocketPacket.packetFromEmitAckWithData(args, id: ack ?? -1, nsp: this.nsp) let str = packet.createAck() @@ -344,13 +305,10 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient } } - public func engineDidClose(reason: String) { - _connected = false - _connecting = false - - if closed || !reconnects { + public func engineDidClose(reason:String) { + if status == SocketIOClientStatus.Closed || !reconnects { didDisconnect(reason) - } else if !reconnecting { + } else if status != SocketIOClientStatus.Reconnecting { handleEvent("reconnect", data: [reason], isInternalMessage: true) tryReconnect() } @@ -368,12 +326,12 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient /** Causes an event to be handled. Only use if you know what you're doing. */ - public func handleEvent(event: String, data: [AnyObject]?, isInternalMessage: Bool = false, - wantsAck ack: Int? = nil) { - // println("Should do event: \(event) with data: \(data)") - if !connected && !isInternalMessage { + public func handleEvent(event:String, data:[AnyObject]?, isInternalMessage:Bool = false, + wantsAck ack:Int? = nil) { + guard status == SocketIOClientStatus.Connected && !isInternalMessage else { return } + // println("Should do event: \(event) with data: \(data)") SocketLogger.log("Handling event: %@ with data: %@", client: self, args: event, data ?? "") @@ -385,9 +343,9 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient } for handler in handlers where handler.event == event { - if ack != nil { + if let ack = ack { dispatch_async(handleQueue) {[weak self] in - handler.executeCallback(data, withAck: ack!, withSocket: self) + handler.executeCallback(data, withAck: ack, withSocket: self) } } else { dispatch_async(handleQueue) { @@ -418,6 +376,14 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient } } + /** + Joins namespace / + */ + public func joinNamespace(namespace:String) { + self.nsp = namespace + joinNamespace() + } + /** Removes handler(s) */ @@ -481,30 +447,26 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient Trieds to reconnect to the server. */ public func reconnect() { - _connected = false - _connecting = false - _reconnecting = false - + status = SocketIOClientStatus.Reconnecting engine?.stopPolling() tryReconnect() } @objc private func tryReconnect() { + guard status != SocketIOClientStatus.Connected else { + return + } if reconnectAttempts != -1 && currentReconnectAttempt + 1 > reconnectAttempts || !reconnects { clearReconnectTimer() didDisconnect("Reconnect Failed") - return - } else if connected { - _connecting = false - _reconnecting = false return } if reconnectTimer == nil { SocketLogger.log("Starting reconnect", client: self) - _reconnecting = true + status = SocketIOClientStatus.Reconnecting dispatch_async(dispatch_get_main_queue()) {[weak self] in if let this = self { diff --git a/SocketIOClientSwift/SocketTypes.swift b/SocketIOClientSwift/SocketTypes.swift index 342564c..263653f 100644 --- a/SocketIOClientSwift/SocketTypes.swift +++ b/SocketIOClientSwift/SocketTypes.swift @@ -29,4 +29,10 @@ public typealias AckEmitter = (AnyObject...) -> Void public typealias AckEmitterObjectiveC = (NSArray) -> Void public typealias NormalCallback = (NSArray?, AckEmitter?) -> Void public typealias NormalCallbackObjectiveC = (NSArray?, AckEmitterObjectiveC?) -> Void -public typealias OnAckCallback = (timeoutAfter: UInt64, callback: AckCallback) -> Void +public typealias OnAckCallback = (timeoutAfter:UInt64, callback:AckCallback) -> Void + + +@objc public enum SocketIOClientStatus: Int { + case NotConnected, Closed, Connecting, Connected, Reconnecting + +}