diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 9c0c5aa..0eff01d 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -68,7 +68,12 @@ class SocketParserTest: XCTestCase { func testInvalidInput() { let message = "8" - XCTAssertNil(SocketParser.parseString(message)) + switch SocketParser.parseString(message) { + case .Left(_): + return + case .Right(_): + XCTFail("Created packet when shouldn't have") + } } func testGenericParser() { @@ -83,7 +88,7 @@ class SocketParserTest: XCTestCase { let validValues = SocketParserTest.packetTypes[message]! let packet = SocketParser.parseString(message) let type = message.substringWithRange(Range(start: message.startIndex, end: message.startIndex.advancedBy(1))) - if let packet = packet { + if case let .Right(packet) = packet { XCTAssertEqual(packet.type, SocketPacket.PacketType(str:type)!) XCTAssertEqual(packet.nsp, validValues.0) XCTAssertTrue((packet.data as NSArray).isEqualToArray(validValues.1)) diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index fd9b654..a466083 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -65,8 +65,9 @@ public final class SocketEngine: NSObject, WebSocketDelegate { var cookies: [NSHTTPCookie]? var sid = "" var socketPath = "" - var urlPolling: String? - var urlWebSocket: String? + var urlPolling = "" + var urlWebSocket = "" + var ws: WebSocket? @objc public enum PacketType: Int { @@ -129,7 +130,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { stopPolling() } - private func createBinaryDataForSend(data: NSData) -> (NSData?, String?) { + private func createBinaryDataForSend(data: NSData) -> Either { if websocket { var byteArray = [UInt8](count: 1, repeatedValue: 0x0) byteArray[0] = 4 @@ -137,23 +138,22 @@ public final class SocketEngine: NSObject, WebSocketDelegate { mutData.appendData(data) - return (mutData, nil) + return .Left(mutData) } else { var str = "b4" str += data.base64EncodedStringWithOptions( NSDataBase64EncodingOptions.Encoding64CharacterLineLength) - return (nil, str) + return .Right(str) } } - private func createURLs(params: [String: AnyObject]?) -> (String?, String?) { + private func createURLs(params: [String: AnyObject]?) -> (String, String) { if client == nil { - return (nil, nil) + return ("", "") } let path = socketPath == "" ? "/socket.io" : socketPath - let url = "\(client!.socketURL)\(path)/?transport=" var urlPolling: String var urlWebSocket: String @@ -189,7 +189,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } private func createWebsocket(andConnect connect: Bool) { - let wsUrl = urlWebSocket! + (sid == "" ? "" : "&sid=\(sid)") + let wsUrl = urlWebSocket + (sid == "" ? "" : "&sid=\(sid)") ws = WebSocket(url: NSURL(string: wsUrl)!, cookies: cookies) @@ -228,7 +228,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } waitingForPoll = true - let req = NSMutableURLRequest(URL: NSURL(string: urlPolling! + "&sid=\(sid)&b64=1")!) + let req = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&sid=\(sid)&b64=1")!) if cookies != nil { let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) @@ -318,7 +318,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { postWait.removeAll(keepCapacity: false) - let req = NSMutableURLRequest(URL: NSURL(string: urlPolling! + "&sid=\(sid)")!) + let req = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&sid=\(sid)")!) if let cookies = cookies { let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies) @@ -468,7 +468,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { return } - let reqPolling = NSMutableURLRequest(URL: NSURL(string: urlPolling! + "&b64=1")!) + let reqPolling = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&b64=1")!) if cookies != nil { let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) @@ -581,9 +581,9 @@ public final class SocketEngine: NSObject, WebSocketDelegate { postWait.append(strMsg) for data in datas ?? [] { - let (_, b64Data) = createBinaryDataForSend(data) - - postWait.append(b64Data!) + if case let .Right(bin) = createBinaryDataForSend(data) { + postWait.append(bin) + } } if !waitingForPost { @@ -600,9 +600,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { ws?.writeString("\(type.rawValue)\(str)") for data in datas ?? [] { - let (data, _) = createBinaryDataForSend(data) - if data != nil { - ws?.writeData(data!) + if case let Either.Left(bin) = createBinaryDataForSend(data) { + ws?.writeData(bin) } } } diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index cd79bde..8582531 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -27,26 +27,7 @@ class SocketParser { private static func isCorrectNamespace(nsp: String, _ socket: SocketIOClient) -> Bool { return nsp == socket.nsp } - - private static func handleEvent(p: SocketPacket, socket: SocketIOClient) { - guard isCorrectNamespace(p.nsp, socket) else { return } - - socket.handleEvent(p.event, data: p.args ?? [], - isInternalMessage: false, wantsAck: p.id) - } - - private static func handleAck(p: SocketPacket, socket: SocketIOClient) { - guard isCorrectNamespace(p.nsp, socket) else { return } - - socket.handleAck(p.id, data: p.data) - } - - private static func handleBinary(p: SocketPacket, socket: SocketIOClient) { - guard isCorrectNamespace(p.nsp, socket) else { return } - - socket.waitingData.append(p) - } - + private static func handleConnect(p: SocketPacket, socket: SocketIOClient) { if p.nsp == "/" && socket.nsp != "/" { socket.joinNamespace() @@ -57,14 +38,37 @@ class SocketParser { } } - static func parseString(message: String) -> SocketPacket? { + private static func handlePacket(pack: SocketPacket, withSocket socket: SocketIOClient) { + guard isCorrectNamespace(pack.nsp, socket) else { return } + + switch pack.type { + case .Event: + socket.handleEvent(pack.event, data: pack.args ?? [], + isInternalMessage: false, wantsAck: pack.id) + case .Ack: + socket.handleAck(pack.id, data: pack.data) + case .BinaryEvent: + socket.waitingData.append(pack) + case .BinaryAck: + socket.waitingData.append(pack) + case .Connect: + handleConnect(pack, socket: socket) + case .Disconnect: + socket.didDisconnect("Got Disconnect") + case .Error: + socket.didError("Error: \(pack.data)") + } + } + + static func parseString(message: String) -> Either { var parser = SocketStringReader(message: message) - guard let type = SocketPacket.PacketType(str: parser.read(1)) - else {return nil} + guard let type = SocketPacket.PacketType(str: parser.read(1)) else { + return .Left("Invalid packet type") + } if !parser.hasNext { - return SocketPacket(type: type, nsp: "/") + return .Right(SocketPacket(type: type, nsp: "/")) } var namespace: String? @@ -74,7 +78,7 @@ class SocketParser { if let holders = Int(parser.readUntilStringOccurence("-")) { placeholders = holders } else { - return nil + return .Left("Invalid packet") } } @@ -83,8 +87,8 @@ class SocketParser { } if !parser.hasNext { - return SocketPacket(type: type, id: -1, - nsp: namespace ?? "/", placeholders: placeholders) + return .Right(SocketPacket(type: type, id: -1, + nsp: namespace ?? "/", placeholders: placeholders)) } var idString = "" @@ -100,21 +104,28 @@ class SocketParser { let d = message[parser.currentIndex.advancedBy(1).. AnyObject? { + private static func parseData(data: String) -> Either { let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) do { - return try NSJSONSerialization.JSONObjectWithData(stringData!, - options: NSJSONReadingOptions.MutableContainers) + if let arr = try NSJSONSerialization.JSONObjectWithData(stringData!, + options: NSJSONReadingOptions.MutableContainers) as? [AnyObject] { + return .Right(arr) + } else { + return .Left("Expected data array") + } } catch { - Logger.error("Parsing JSON: %@", type: "SocketParser", args: data) - return nil + return .Left("Error parsing data for packet") } } @@ -124,30 +135,13 @@ class SocketParser { Logger.log("Parsing %@", type: "SocketParser", args: message) - guard let pack = parseString(message) else { - Logger.error("Parsing message: %@", type: "SocketParser", args: message) - return + switch parseString(message) { + case .Left(let err): + Logger.error("\(err): %@", type: "SocketParser", args: message) + case .Right(let pack): + Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description) + handlePacket(pack, withSocket: socket) } - - Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description) - - switch pack.type { - case .Event: - handleEvent(pack, socket: socket) - case .Ack: - handleAck(pack, socket: socket) - case .BinaryEvent: - handleBinary(pack, socket: socket) - case .BinaryAck: - handleBinary(pack, socket: socket) - case .Connect: - handleConnect(pack, socket: socket) - case .Disconnect: - socket.didDisconnect("Got Disconnect") - case .Error: - socket.didError("Error: \(pack.data)") - } - } static func parseBinaryData(data: NSData, socket: SocketIOClient) { @@ -156,9 +150,8 @@ class SocketParser { return } - let shouldExecute = socket.waitingData[socket.waitingData.count - 1].addData(data) - - guard shouldExecute else { + // Should execute event? + guard socket.waitingData[socket.waitingData.count - 1].addData(data) else { return } diff --git a/SocketIOClientSwift/SocketTypes.swift b/SocketIOClientSwift/SocketTypes.swift index 09fb67a..ed091f9 100644 --- a/SocketIOClientSwift/SocketTypes.swift +++ b/SocketIOClientSwift/SocketTypes.swift @@ -28,3 +28,7 @@ public typealias AckCallback = ([AnyObject]) -> Void public typealias NormalCallback = ([AnyObject], SocketAckEmitter?) -> Void public typealias OnAckCallback = (timeoutAfter: UInt64, callback: AckCallback) -> Void +enum Either { + case Left(E) + case Right(V) +} \ No newline at end of file