This commit is contained in:
Erik 2016-06-14 20:41:59 -04:00
parent 7500ea83a0
commit 9a4ec5a82a
27 changed files with 552 additions and 545 deletions

View File

@ -536,9 +536,11 @@
};
572EF2371B51F18A00EEBB58 = {
CreatedOnToolsVersion = 6.4;
LastSwiftMigration = 0800;
};
572EF2411B51F18A00EEBB58 = {
CreatedOnToolsVersion = 6.4;
LastSwiftMigration = 0800;
};
};
};
@ -1081,6 +1083,7 @@
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@ -1132,6 +1135,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.socket.$(PRODUCT_NAME:rfc1034identifier)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@ -1188,6 +1192,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@ -1234,6 +1239,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.socket.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 3.0;
};
name = Release;
};

View File

@ -15,7 +15,7 @@ class SocketAckManagerTest: XCTestCase {
func testAddAcks() {
let callbackExpection = self.expectation(withDescription: "callbackExpection")
let itemsArray = ["Hi", "ho"]
func callback(items: [AnyObject]) {
func callback(_ items: [AnyObject]) {
callbackExpection.fulfill()
}
ackManager.addAck(1, callback: callback)

View File

@ -10,13 +10,13 @@ import XCTest
@testable import SocketIOClientSwift
class SocketBasicPacketTest: XCTestCase {
let data = "test".data(using: NSUTF8StringEncoding)!
let data2 = "test2".data(using: NSUTF8StringEncoding)!
let data = "test".data(using: String.Encoding.utf8)!
let data2 = "test2".data(using: String.Encoding.utf8)!
func testEmpyEmit() {
let expectedSendString = "2[\"test\"]"
let sendData = ["test"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -24,7 +24,7 @@ class SocketBasicPacketTest: XCTestCase {
func testNullEmit() {
let expectedSendString = "2[\"test\",null]"
let sendData = ["test", NSNull()]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -32,7 +32,7 @@ class SocketBasicPacketTest: XCTestCase {
func testStringEmit() {
let expectedSendString = "2[\"test\",\"foo bar\"]"
let sendData = ["test", "foo bar"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -40,7 +40,7 @@ class SocketBasicPacketTest: XCTestCase {
func testStringEmitWithQuotes() {
let expectedSendString = "2[\"test\",\"\\\"he\\\"llo world\\\"\"]"
let sendData = ["test", "\"he\"llo world\""]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -48,7 +48,7 @@ class SocketBasicPacketTest: XCTestCase {
func testJSONEmit() {
let expectedSendString = "2[\"test\",{\"test\":\"hello\",\"hello\":1,\"foobar\":true,\"null\":null}]"
let sendData = ["test", ["foobar": true, "hello": 1, "test": "hello", "null": NSNull()]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -56,7 +56,7 @@ class SocketBasicPacketTest: XCTestCase {
func testArrayEmit() {
let expectedSendString = "2[\"test\",[\"hello\",1,{\"test\":\"test\"}]]"
let sendData = ["test", ["hello", 1, ["test": "test"]]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -64,7 +64,7 @@ class SocketBasicPacketTest: XCTestCase {
func testBinaryEmit() {
let expectedSendString = "51-[\"test\",{\"_placeholder\":true,\"num\":0}]"
let sendData = ["test", data]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData as [AnyObject], id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data])
@ -73,7 +73,7 @@ class SocketBasicPacketTest: XCTestCase {
func testMultipleBinaryEmit() {
let expectedSendString = "52-[\"test\",{\"data1\":{\"_placeholder\":true,\"num\":0},\"data2\":{\"_placeholder\":true,\"num\":1}}]"
let sendData = ["test", ["data1": data, "data2": data2]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data, data2])
@ -82,7 +82,7 @@ class SocketBasicPacketTest: XCTestCase {
func testEmitWithAck() {
let expectedSendString = "20[\"test\"]"
let sendData = ["test"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -90,7 +90,7 @@ class SocketBasicPacketTest: XCTestCase {
func testEmitDataWithAck() {
let expectedSendString = "51-0[\"test\",{\"_placeholder\":true,\"num\":0}]"
let sendData = ["test", data]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/", ack: false)
let packet = SocketPacket.packetFromEmit(sendData as [AnyObject], id: 0, nsp: "/", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data])
@ -99,7 +99,7 @@ class SocketBasicPacketTest: XCTestCase {
// Acks
func testEmptyAck() {
let expectedSendString = "30[]"
let packet = SocketPacket.packetFromEmit(items: [], id: 0, nsp: "/", ack: true)
let packet = SocketPacket.packetFromEmit([], id: 0, nsp: "/", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -107,7 +107,7 @@ class SocketBasicPacketTest: XCTestCase {
func testNullAck() {
let expectedSendString = "30[null]"
let sendData = [NSNull()]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -115,7 +115,7 @@ class SocketBasicPacketTest: XCTestCase {
func testStringAck() {
let expectedSendString = "30[\"test\"]"
let sendData = ["test"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -123,7 +123,7 @@ class SocketBasicPacketTest: XCTestCase {
func testJSONAck() {
let expectedSendString = "30[{\"test\":\"hello\",\"hello\":1,\"foobar\":true,\"null\":null}]"
let sendData = [["foobar": true, "hello": 1, "test": "hello", "null": NSNull()]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -131,7 +131,7 @@ class SocketBasicPacketTest: XCTestCase {
func testBinaryAck() {
let expectedSendString = "61-0[{\"_placeholder\":true,\"num\":0}]"
let sendData = [data]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data])
@ -140,7 +140,7 @@ class SocketBasicPacketTest: XCTestCase {
func testMultipleBinaryAck() {
let expectedSendString = "62-0[{\"data2\":{\"_placeholder\":true,\"num\":0},\"data1\":{\"_placeholder\":true,\"num\":1}}]"
let sendData = [["data1": data, "data2": data2]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data2, data])
@ -148,10 +148,10 @@ class SocketBasicPacketTest: XCTestCase {
func testBinaryStringPlaceholderInMessage() {
let engineString = "52-[\"test\",\"~~0\",{\"num\":0,\"_placeholder\":true},{\"_placeholder\":true,\"num\":1}]"
let socket = SocketIOClient(socketURL: NSURL())
let socket = SocketIOClient(socketURL: URL(string: "http://localhost/")!)
socket.setTestable()
if case let .Right(packet) = socket.parseString(engineString) {
if case let .right(packet) = socket.parseString(engineString) {
var packet = packet
XCTAssertEqual(packet.event, "test")
packet.addData(data)

View File

@ -15,8 +15,8 @@ class SocketEngineTest: XCTestCase {
override func setUp() {
super.setUp()
client = SocketIOClient(socketURL: NSURL(string: "http://localhost")!)
engine = SocketEngine(client: client, url: NSURL(string: "http://localhost")!, options: nil)
client = SocketIOClient(socketURL: URL(string: "http://localhost")!)
engine = SocketEngine(client: client, url: URL(string: "http://localhost")!, options: nil)
client.setTestable()
}

View File

@ -10,13 +10,13 @@ import XCTest
@testable import SocketIOClientSwift
class SocketNamespacePacketTest: XCTestCase {
let data = "test".data(using: NSUTF8StringEncoding)!
let data2 = "test2".data(using: NSUTF8StringEncoding)!
let data = "test".data(using: String.Encoding.utf8)!
let data2 = "test2".data(using: String.Encoding.utf8)!
func testEmpyEmit() {
let expectedSendString = "2/swift,[\"test\"]"
let sendData = ["test"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -24,7 +24,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testNullEmit() {
let expectedSendString = "2/swift,[\"test\",null]"
let sendData = ["test", NSNull()]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -32,7 +32,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testStringEmit() {
let expectedSendString = "2/swift,[\"test\",\"foo bar\"]"
let sendData = ["test", "foo bar"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -40,7 +40,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testJSONEmit() {
let expectedSendString = "2/swift,[\"test\",{\"test\":\"hello\",\"hello\":1,\"foobar\":true,\"null\":null}]"
let sendData = ["test", ["foobar": true, "hello": 1, "test": "hello", "null": NSNull()]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -48,7 +48,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testArrayEmit() {
let expectedSendString = "2/swift,[\"test\",[\"hello\",1,{\"test\":\"test\"}]]"
let sendData = ["test", ["hello", 1, ["test": "test"]]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -56,7 +56,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testBinaryEmit() {
let expectedSendString = "51-/swift,[\"test\",{\"_placeholder\":true,\"num\":0}]"
let sendData = ["test", data]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData as [AnyObject], id: -1, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data])
@ -65,7 +65,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testMultipleBinaryEmit() {
let expectedSendString = "52-/swift,[\"test\",{\"data1\":{\"_placeholder\":true,\"num\":0},\"data2\":{\"_placeholder\":true,\"num\":1}}]"
let sendData = ["test", ["data1": data, "data2": data2]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: -1, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: -1, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data, data2])
@ -74,7 +74,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testEmitWithAck() {
let expectedSendString = "2/swift,0[\"test\"]"
let sendData = ["test"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -82,7 +82,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testEmitDataWithAck() {
let expectedSendString = "51-/swift,0[\"test\",{\"_placeholder\":true,\"num\":0}]"
let sendData = ["test", data]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/swift", ack: false)
let packet = SocketPacket.packetFromEmit(sendData as [AnyObject], id: 0, nsp: "/swift", ack: false)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data])
@ -91,7 +91,7 @@ class SocketNamespacePacketTest: XCTestCase {
// Acks
func testEmptyAck() {
let expectedSendString = "3/swift,0[]"
let packet = SocketPacket.packetFromEmit(items: [], id: 0, nsp: "/swift", ack: true)
let packet = SocketPacket.packetFromEmit([], id: 0, nsp: "/swift", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -99,7 +99,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testNullAck() {
let expectedSendString = "3/swift,0[null]"
let sendData = [NSNull()]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/swift", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/swift", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -107,7 +107,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testStringAck() {
let expectedSendString = "3/swift,0[\"test\"]"
let sendData = ["test"]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/swift", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/swift", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -115,7 +115,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testJSONAck() {
let expectedSendString = "3/swift,0[{\"test\":\"hello\",\"hello\":1,\"foobar\":true,\"null\":null}]"
let sendData = [["foobar": true, "hello": 1, "test": "hello", "null": NSNull()]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/swift", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/swift", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
}
@ -123,7 +123,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testBinaryAck() {
let expectedSendString = "61-/swift,0[{\"_placeholder\":true,\"num\":0}]"
let sendData = [data]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/swift", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/swift", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data])
@ -132,7 +132,7 @@ class SocketNamespacePacketTest: XCTestCase {
func testMultipleBinaryAck() {
let expectedSendString = "62-/swift,0[{\"data2\":{\"_placeholder\":true,\"num\":0},\"data1\":{\"_placeholder\":true,\"num\":1}}]"
let sendData = [["data1": data, "data2": data2]]
let packet = SocketPacket.packetFromEmit(items: sendData, id: 0, nsp: "/swift", ack: true)
let packet = SocketPacket.packetFromEmit(sendData, id: 0, nsp: "/swift", ack: true)
XCTAssertEqual(packet.packetString, expectedSendString)
XCTAssertEqual(packet.binary, [data2, data])

View File

@ -46,7 +46,7 @@
- (void)testSocketManager {
SocketClientManager* manager = [SocketClientManager sharedManager];
[manager addSocketWithSocket:self.socket labeledAs:@"test"];
[manager addSocket:self.socket labeledAs:@"test"];
[manager removeSocketWithLabel:@"test"];
}

View File

@ -10,10 +10,10 @@ import XCTest
@testable import SocketIOClientSwift
class SocketParserTest: XCTestCase {
let testSocket = SocketIOClient(socketURL: NSURL())
let testSocket = SocketIOClient(socketURL: URL(string: "http://localhost/")!)
//Format key: message; namespace-data-binary-id
static let packetTypes: [String: (String, [AnyObject], [NSData], Int)] = [
static let packetTypes: [String: (String, [AnyObject], [Data], Int)] = [
"0": ("/", [], [], -1), "1": ("/", [], [], -1),
"25[\"test\"]": ("/", ["test"], [], 5),
"2[\"test\",\"~~0\"]": ("/", ["test", "~~0"], [], -1),
@ -31,97 +31,97 @@ class SocketParserTest: XCTestCase {
func testDisconnect() {
let message = "1"
validateParseResult(message: message)
validateParseResult(message)
}
func testConnect() {
let message = "0"
validateParseResult(message: message)
validateParseResult(message)
}
func testDisconnectNameSpace() {
let message = "1/swift"
validateParseResult(message: message)
validateParseResult(message)
}
func testConnecttNameSpace() {
let message = "0/swift"
validateParseResult(message: message)
validateParseResult(message)
}
func testIdEvent() {
let message = "25[\"test\"]"
validateParseResult(message: message)
validateParseResult(message)
}
func testBinaryPlaceholderAsString() {
let message = "2[\"test\",\"~~0\"]"
validateParseResult(message: message)
validateParseResult(message)
}
func testNameSpaceArrayParse() {
let message = "2/swift,[\"testArrayEmitReturn\",[\"test3\",\"test4\"]]"
validateParseResult(message: message)
validateParseResult(message)
}
func testNameSpaceArrayAckParse() {
let message = "3/swift,0[[\"test3\",\"test4\"]]"
validateParseResult(message: message)
validateParseResult(message)
}
func testNameSpaceBinaryEventParse() {
let message = "51-/swift,[\"testMultipleItemsWithBufferEmitReturn\",[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]"
validateParseResult(message: message)
validateParseResult(message)
}
func testNameSpaceBinaryAckParse() {
let message = "61-/swift,19[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]"
validateParseResult(message: message)
validateParseResult(message)
}
func testNamespaceErrorParse() {
let message = "4/swift,"
validateParseResult(message: message)
validateParseResult(message)
}
func testErrorTypeString() {
let message = "4\"ERROR\""
validateParseResult(message: message)
validateParseResult(message)
}
func testErrorTypeDictionary() {
let message = "4{\"test\":2}"
validateParseResult(message: message)
validateParseResult(message)
}
func testErrorTypeInt() {
let message = "41"
validateParseResult(message: message)
validateParseResult(message)
}
func testInvalidInput() {
let message = "8"
switch testSocket.parseString(message) {
case .Left(_):
case .left(_):
return
case .Right(_):
case .right(_):
XCTFail("Created packet when shouldn't have")
}
}
func testGenericParser() {
var parser = SocketStringReader(message: "61-/swift,")
XCTAssertEqual(parser.read(length: 1), "6")
XCTAssertEqual(parser.read(1), "6")
XCTAssertEqual(parser.currentCharacter, "1")
XCTAssertEqual(parser.readUntilStringOccurence("-"), "1")
XCTAssertEqual(parser.currentCharacter, "/")
}
func validateParseResult(message: String) {
func validateParseResult(_ message: String) {
let validValues = SocketParserTest.packetTypes[message]!
let packet = testSocket.parseString(message)
let type = message.substring(with: Range<String.Index>(message.startIndex..<message.characters.index(message.startIndex, offsetBy: 1)))
if case let .Right(packet) = packet {
if case let .right(packet) = packet {
XCTAssertEqual(packet.type, SocketPacket.PacketType(rawValue: Int(type) ?? -1)!)
XCTAssertEqual(packet.nsp, validValues.0)
XCTAssertTrue((packet.data as NSArray).isEqual(to: validValues.1), "\(packet.data)")

View File

@ -10,13 +10,13 @@ import XCTest
@testable import SocketIOClientSwift
class SocketSideEffectTest: XCTestCase {
let data = "test".data(using: NSUTF8StringEncoding)!
let data2 = "test2".data(using: NSUTF8StringEncoding)!
let data = "test".data(using: String.Encoding.utf8)!
let data2 = "test2".data(using: String.Encoding.utf8)!
private var socket: SocketIOClient!
override func setUp() {
super.setUp()
socket = SocketIOClient(socketURL: NSURL())
socket = SocketIOClient(socketURL: URL(string: "http://localhost/")!)
socket.setTestable()
}
@ -55,7 +55,7 @@ class SocketSideEffectTest: XCTestCase {
}
socket.parseSocketMessage("61-0[{\"_placeholder\":true,\"num\":0},{\"test\":true}]")
socket.parseBinaryData(NSData())
socket.parseBinaryData(Data())
waitForExpectations(withTimeout: 3, handler: nil)
}
@ -83,7 +83,7 @@ class SocketSideEffectTest: XCTestCase {
func testHandleOnceEvent() {
let expect = expectation(withDescription: "handled event")
socket.once(event: "test") {data, ack in
socket.once("test") {data, ack in
XCTAssertEqual(data[0] as? String, "hello world")
XCTAssertEqual(self.socket.testHandlers.count, 0)
expect.fulfill()
@ -140,7 +140,7 @@ class SocketSideEffectTest: XCTestCase {
func testSocketDataToAnyObject() {
let data = ["test", 1, 2.2, ["Hello": 2, "bob": 2.2], true, [1, 2], [1.1, 2]] as [SocketData]
XCTAssertEqual(data.count, socket.socketDataToAnyObject(data: data).count)
XCTAssertEqual(data.count, socket.socketDataToAnyObject(data).count)
}
func testHandleMultipleBinaryEvent() {

View File

@ -24,8 +24,8 @@
import Foundation
extension NSCharacterSet {
class var allowedURLCharacterSet: NSCharacterSet {
return NSCharacterSet(charactersIn: "!*'();:@&=+$,/?%#[]\" {}").inverted
extension CharacterSet {
static var allowedURLCharacterSet: CharacterSet {
return CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[]\" {}").inverted
}
}

View File

@ -36,7 +36,7 @@ public final class SocketAckEmitter : NSObject {
public func with(_ items: SocketData...) {
guard ackNum != -1 else { return }
socket.emitAck(ackNum, with: socket.socketDataToAnyObject(data: items))
socket.emitAck(ackNum, with: socket.socketDataToAnyObject(items))
}
public func with(_ items: [AnyObject]) {

View File

@ -59,7 +59,7 @@ struct SocketAckManager {
mutating func executeAck(_ ack: Int, items: [AnyObject]) {
let callback = acks.remove(SocketAck(ack: ack))
dispatch_async(dispatch_get_main_queue()) {
DispatchQueue.main.async {
callback?.callback(items)
}
}
@ -67,7 +67,7 @@ struct SocketAckManager {
mutating func timeoutAck(_ ack: Int) {
let callback = acks.remove(SocketAck(ack: ack))
dispatch_async(dispatch_get_main_queue()) {
DispatchQueue.main.async {
callback?.callback(["NO ACK"])
}
}

View File

@ -58,7 +58,7 @@ public final class SocketClientManager : NSObject {
}
}
public func addSocket(socket: SocketIOClient, labeledAs label: String) {
public func addSocket(_ socket: SocketIOClient, labeledAs label: String) {
sockets[label] = socket
}
@ -66,7 +66,7 @@ public final class SocketClientManager : NSObject {
return sockets.removeValue(forKey: label)
}
public func removeSocket(socket: SocketIOClient) -> SocketIOClient? {
public func removeSocket(_ socket: SocketIOClient) -> SocketIOClient? {
var returnSocket: SocketIOClient?
for (label, dictSocket) in sockets where dictSocket === socket {

View File

@ -25,9 +25,9 @@
import Foundation
public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWebsocket {
public let emitQueue = dispatch_queue_create("com.socketio.engineEmitQueue", DISPATCH_QUEUE_SERIAL)!
public let handleQueue = dispatch_queue_create("com.socketio.engineHandleQueue", DISPATCH_QUEUE_SERIAL)!
public let parseQueue = dispatch_queue_create("com.socketio.engineParseQueue", DISPATCH_QUEUE_SERIAL)!
public let emitQueue = DispatchQueue(label: "com.socketio.engineEmitQueue", attributes: DispatchQueueAttributes.serial)
public let handleQueue = DispatchQueue(label: "com.socketio.engineHandleQueue", attributes: DispatchQueueAttributes.serial)
public let parseQueue = DispatchQueue(label: "com.socketio.engineParseQueue", attributes: DispatchQueueAttributes.serial)
public var connectParams: [String: AnyObject]? {
didSet {
@ -41,7 +41,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
public private(set) var closed = false
public private(set) var connected = false
public private(set) var cookies: [NSHTTPCookie]?
public private(set) var cookies: [HTTPCookie]?
public private(set) var doubleEncodeUTF8 = true
public private(set) var extraHeaders: [String: String]?
public private(set) var fastUpgrade = false
@ -50,20 +50,20 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
public private(set) var invalidated = false
public private(set) var polling = true
public private(set) var probing = false
public private(set) var session: NSURLSession?
public private(set) var session: URLSession?
public private(set) var sid = ""
public private(set) var socketPath = "/engine.io/"
public private(set) var urlPolling = NSURL()
public private(set) var urlWebSocket = NSURL()
public private(set) var urlPolling = URL(string: "http://localhost/")!
public private(set) var urlWebSocket = URL(string: "http://localhost/")!
public private(set) var websocket = false
public private(set) var ws: WebSocket?
public weak var client: SocketEngineClient?
private weak var sessionDelegate: NSURLSessionDelegate?
private weak var sessionDelegate: URLSessionDelegate?
private let logType = "SocketEngine"
private let url: NSURL
private let url: URL
private var pingInterval: Double?
private var pingTimeout = 0.0 {
@ -80,7 +80,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
private var selfSigned = false
private var voipEnabled = false
public init(client: SocketEngineClient, url: NSURL, options: Set<SocketIOClientOption>) {
public init(client: SocketEngineClient, url: URL, options: Set<SocketIOClientOption>) {
self.client = client
self.url = url
@ -120,7 +120,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
(urlPolling, urlWebSocket) = createURLs()
}
public convenience init(client: SocketEngineClient, url: NSURL, options: NSDictionary?) {
public convenience init(client: SocketEngineClient, url: URL, options: NSDictionary?) {
self.init(client: client, url: url, options: options?.toSocketOptionsSet() ?? [])
}
@ -131,11 +131,11 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
}
private func checkAndHandleEngineError(_ msg: String) {
guard let stringData = msg.data(using: NSUTF8StringEncoding,
guard let stringData = msg.data(using: String.Encoding.utf8,
allowLossyConversion: false) else { return }
do {
if let dict = try NSJSONSerialization.jsonObject(with: stringData, options: .mutableContainers) as? NSDictionary {
if let dict = try JSONSerialization.jsonObject(with: stringData, options: .mutableContainers) as? NSDictionary {
guard let error = dict["message"] as? String else { return }
/*
@ -144,10 +144,10 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
2: Bad handshake request
3: Bad request
*/
didError(error: error)
didError(error)
}
} catch {
didError(error: "Got unknown error from server \(msg)")
didError("Got unknown error from server \(msg)")
}
}
@ -156,7 +156,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
// binary in base64 string
let noPrefix = message[message.characters.index(message.startIndex, offsetBy: 2)..<message.endIndex]
if let data = NSData(base64Encoded: noPrefix, options: .ignoreUnknownCharacters) {
if let data = Data(base64Encoded: noPrefix, options: NSData.Base64EncodingOptions(rawValue: 0)) {
client?.parseEngineBinaryData(data)
}
@ -180,7 +180,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
public func connect() {
if connected {
DefaultSocketLogger.Logger.error("Engine tried opening while connected. Assuming this was a reconnect", type: logType)
disconnect(reason: "reconnect")
disconnect("reconnect")
}
DefaultSocketLogger.Logger.log("Starting engine. Server: %@", type: logType, args: url)
@ -198,7 +198,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
let reqPolling = NSMutableURLRequest(url: urlPolling)
if cookies != nil {
let headers = NSHTTPCookie.requestHeaderFields(with: cookies!)
let headers = HTTPCookie.requestHeaderFields(with: cookies!)
reqPolling.allHTTPHeaderFields = headers
}
@ -208,18 +208,18 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
}
}
dispatch_async(emitQueue) {
self.doLongPoll(for: reqPolling)
(emitQueue).async {
self.doLongPoll(for: reqPolling as URLRequest)
}
}
private func createURLs() -> (NSURL, NSURL) {
private func createURLs() -> (URL, URL) {
if client == nil {
return (NSURL(), NSURL())
return (URL(string: "http://localhost/")!, URL(string: "http://localhost/")!)
}
let urlPolling = NSURLComponents(string: url.absoluteString)!
let urlWebSocket = NSURLComponents(string: url.absoluteString)!
var urlPolling = URLComponents(string: url.absoluteString!)!
var urlWebSocket = URLComponents(string: url.absoluteString!)!
var queryString = ""
urlWebSocket.path = socketPath
@ -252,7 +252,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
ws = WebSocket(url: urlWebSocketWithSid)
if cookies != nil {
let headers = NSHTTPCookie.requestHeaderFields(with: cookies!)
let headers = HTTPCookie.requestHeaderFields(with: cookies!)
for (key, value) in headers {
ws?.headers[key] = value
}
@ -273,20 +273,20 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
ws?.connect()
}
public func didError(error: String) {
public func didError(_ error: String) {
DefaultSocketLogger.Logger.error("%@", type: logType, args: error)
client?.engineDidError(reason: error)
disconnect(reason: error)
client?.engineDidError(error)
disconnect(error)
}
public func disconnect(reason: String) {
public func disconnect(_ reason: String) {
guard connected else { return closeOutEngine() }
DefaultSocketLogger.Logger.log("Engine is being closed.", type: logType)
if closed {
closeOutEngine()
client?.engineDidClose(reason: reason)
client?.engineDidClose(reason)
return
}
@ -301,7 +301,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
// We need to take special care when we're polling that we send it ASAP
// Also make sure we're on the emitQueue since we're touching postWait
private func disconnectPolling() {
dispatch_sync(emitQueue) {
emitQueue.sync {
self.postWait.append(String(SocketEnginePacketType.close.rawValue))
let req = self.createRequestForPostWithPostWait()
self.doRequest(for: req) {_, _, _ in }
@ -326,7 +326,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
private func flushProbeWait() {
DefaultSocketLogger.Logger.log("Flushing probe wait", type: logType)
dispatch_async(emitQueue) {
emitQueue.async {
for waiter in self.probeWait {
self.write(waiter.msg, withType: waiter.type, withData: waiter.data)
}
@ -345,14 +345,14 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
guard let ws = self.ws else { return }
for msg in postWait {
ws.writeString(str: msg)
ws.writeString(msg)
}
postWait.removeAll(keepingCapacity: true)
}
private func handleClose(reason: String) {
client?.engineDidClose(reason: reason)
private func handleClose(_ reason: String) {
client?.engineDidClose(reason)
}
private func handleMessage(_ message: String) {
@ -363,11 +363,11 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
doPoll()
}
private func handleOpen(openMessage: String) {
let mesData = openMessage.data(using: NSUTF8StringEncoding, allowLossyConversion: false)!
private func handleOpen(_ openMessage: String) {
let mesData = openMessage.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
let json = try NSJSONSerialization.jsonObject(with: mesData,
options: NSJSONReadingOptions.allowFragments) as? NSDictionary
let json = try JSONSerialization.jsonObject(with: mesData,
options: JSONSerialization.ReadingOptions.allowFragments) as? NSDictionary
if let sid = json?["sid"] as? String {
let upgradeWs: Bool
@ -395,14 +395,14 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
doPoll()
}
client?.engineDidOpen(reason: "Connect")
client?.engineDidOpen("Connect")
}
} catch {
didError(error: "Error parsing open packet")
didError("Error parsing open packet")
}
}
private func handlePong(pongMessage: String) {
private func handlePong(_ pongMessage: String) {
pongsMissed = 0
// We should upgrade
@ -411,9 +411,10 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
}
}
public func parseEngineData(_ data: NSData) {
public func parseEngineData(_ data: Data) {
DefaultSocketLogger.Logger.log("Got binary data: %@", type: "SocketEngine", args: data)
client?.parseEngineBinaryData(data.subdata(with: NSMakeRange(1, data.length - 1)))
client?.parseEngineBinaryData(data.subdata(in: Range<Int>(uncheckedBounds: (1, data.count - 1))))
}
public func parseEngineMessage(_ message: String, fromPolling: Bool) {
@ -431,7 +432,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
}
if fromPolling && type != .noop && doubleEncodeUTF8 {
fixedString = fixDoubleUTF8(string: message)
fixedString = fixDoubleUTF8(message)
} else {
fixedString = message
}
@ -443,12 +444,11 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
case .noop:
handleNOOP()
case .pong:
handlePong(pongMessage: fixedString)
handlePong(fixedString)
case .open:
handleOpen(openMessage:
fixedString[fixedString.characters.index(after: fixedString.characters.startIndex)..<fixedString.endIndex])
handleOpen(fixedString[fixedString.characters.index(after: fixedString.characters.startIndex)..<fixedString.endIndex])
case .close:
handleClose(reason: fixedString)
handleClose(fixedString)
default:
DefaultSocketLogger.Logger.log("Got unknown packet type", type: logType)
}
@ -462,9 +462,9 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
polling = true
probing = false
invalidated = false
session = NSURLSession(configuration: .default(),
session = URLSession(configuration: .default(),
delegate: sessionDelegate,
delegateQueue: NSOperationQueue())
delegateQueue: OperationQueue())
sid = ""
waitingForPoll = false
waitingForPost = false
@ -478,7 +478,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
//Server is not responding
if pongsMissed > pongsMissedMax {
client?.engineDidClose(reason: "Ping timeout")
client?.engineDidClose("Ping timeout")
return
}
@ -486,8 +486,8 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
pongsMissed += 1
write("", withType: .ping, withData: [])
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(pingInterval * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue()) {[weak self] in
let time = DispatchTime.now() + Double(Int64(pingInterval * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.after(when: time) {[weak self] in
self?.sendPing()
}
}
@ -505,8 +505,8 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
}
/// Write a message, independent of transport.
public func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [NSData]) {
dispatch_async(emitQueue) {
public func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data]) {
emitQueue.async {
guard self.connected else { return }
if self.websocket {
@ -524,7 +524,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
}
// Delegate methods
public func websocketDidConnect(socket: WebSocket) {
public func websocketDidConnect(_ socket: WebSocket) {
if !forceWebsockets {
probing = true
probeWebSocket()
@ -535,11 +535,11 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
}
}
public func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
public func websocketDidDisconnect(_ socket: WebSocket, error: NSError?) {
probing = false
if closed {
client?.engineDidClose(reason: "Disconnect")
client?.engineDidClose("Disconnect")
return
}
@ -548,9 +548,9 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
websocket = false
if let reason = error?.localizedDescription {
didError(error: reason)
didError(reason)
} else {
client?.engineDidClose(reason: "Socket Disconnected")
client?.engineDidClose("Socket Disconnected")
}
} else {
flushProbeWait()

View File

@ -26,9 +26,9 @@
import Foundation
@objc public protocol SocketEngineClient {
func engineDidError(reason: String)
func engineDidClose(reason: String)
func engineDidOpen(reason: String)
func engineDidError(_ reason: String)
func engineDidClose(_ reason: String)
func engineDidOpen(_ reason: String)
func parseEngineMessage(_ msg: String)
func parseEngineBinaryData(_ data: NSData)
func parseEngineBinaryData(_ data: Data)
}

View File

@ -30,7 +30,7 @@ public protocol SocketEnginePollable : SocketEngineSpec {
/// Holds strings waiting to be sent over polling.
/// You shouldn't need to mess with this.
var postWait: [String] { get set }
var session: NSURLSession? { get }
var session: URLSession? { get }
/// Because socket.io doesn't let you send two polling request at the same time
/// we have to keep track if there's an outstanding poll
var waitingForPoll: Bool { get set }
@ -39,7 +39,7 @@ public protocol SocketEnginePollable : SocketEngineSpec {
var waitingForPost: Bool { get set }
func doPoll()
func sendPollMessage(_ message: String, withType type: SocketEnginePacketType, withData datas: [NSData])
func sendPollMessage(_ message: String, withType type: SocketEnginePacketType, withData datas: [Data])
func stopPolling()
}
@ -47,7 +47,7 @@ public protocol SocketEnginePollable : SocketEngineSpec {
extension SocketEnginePollable {
private func addHeaders(for req: NSMutableURLRequest) {
if cookies != nil {
let headers = NSHTTPCookie.requestHeaderFields(with: cookies!)
let headers = HTTPCookie.requestHeaderFields(with: cookies!)
req.allHTTPHeaderFields = headers
}
@ -58,7 +58,7 @@ extension SocketEnginePollable {
}
}
func createRequestForPostWithPostWait() -> NSURLRequest {
func createRequestForPostWithPostWait() -> URLRequest {
var postStr = ""
for packet in postWait {
@ -71,20 +71,20 @@ extension SocketEnginePollable {
postWait.removeAll(keepingCapacity: false)
let req = NSMutableURLRequest(url: urlPollingWithSid)
let req = NSMutableURLRequest(url: urlPollingWithSid as URL)
addHeaders(for: req)
req.httpMethod = "POST"
req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
let postData = postStr.data(using: NSUTF8StringEncoding,
let postData = postStr.data(using: String.Encoding.utf8,
allowLossyConversion: false)!
req.httpBody = postData
req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length")
req.setValue(String(postData.count), forHTTPHeaderField: "Content-Length")
return req
return req as URLRequest
}
public func doPoll() {
@ -93,13 +93,13 @@ extension SocketEnginePollable {
}
waitingForPoll = true
let req = NSMutableURLRequest(url: urlPollingWithSid)
let req = NSMutableURLRequest(url: urlPollingWithSid as URL)
addHeaders(for: req)
doLongPoll(for: req)
doLongPoll(for: req as URLRequest)
}
func doRequest(for req: NSURLRequest, callbackWith callback: (NSData?, NSURLResponse?, NSError?) -> Void) {
func doRequest(for req: URLRequest, callbackWith callback: (Data?, URLResponse?, NSError?) -> Void) {
if !polling || closed || invalidated || fastUpgrade {
DefaultSocketLogger.Logger.error("Tried to do polling request when not supposed to", type: "SocketEnginePolling")
return
@ -110,7 +110,7 @@ extension SocketEnginePollable {
session?.dataTask(with: req, completionHandler: callback).resume()
}
func doLongPoll(for req: NSURLRequest) {
func doLongPoll(for req: URLRequest) {
doRequest(for: req) {[weak self] data, res, err in
guard let this = self where this.polling else { return }
@ -118,7 +118,7 @@ extension SocketEnginePollable {
DefaultSocketLogger.Logger.error(err?.localizedDescription ?? "Error", type: "SocketEnginePolling")
if this.polling {
this.didError(error: err?.localizedDescription ?? "Error")
this.didError(err?.localizedDescription ?? "Error")
}
return
@ -126,8 +126,8 @@ extension SocketEnginePollable {
DefaultSocketLogger.Logger.log("Got polling response", type: "SocketEnginePolling")
if let str = String(data: data!, encoding: NSUTF8StringEncoding) {
dispatch_async(this.parseQueue) {
if let str = String(data: data!, encoding: String.Encoding.utf8) {
this.parseQueue.async {
this.parsePollingMessage(str)
}
}
@ -163,7 +163,7 @@ extension SocketEnginePollable {
DefaultSocketLogger.Logger.error(err?.localizedDescription ?? "Error", type: "SocketEnginePolling")
if this.polling {
this.didError(error: err?.localizedDescription ?? "Error")
this.didError(err?.localizedDescription ?? "Error")
}
return
@ -171,7 +171,7 @@ extension SocketEnginePollable {
this.waitingForPost = false
dispatch_async(this.emitQueue) {
this.emitQueue.async {
if !this.fastUpgrade {
this.flushWaitingForPost()
this.doPoll()
@ -187,13 +187,13 @@ extension SocketEnginePollable {
while reader.hasNext {
if let n = Int(reader.readUntilStringOccurence(":")) {
let str = reader.read(length: n)
let str = reader.read(n)
dispatch_async(handleQueue) {
(handleQueue).async {
self.parseEngineMessage(str, fromPolling: true)
}
} else {
dispatch_async(handleQueue) {
handleQueue.async {
self.parseEngineMessage(str, fromPolling: true)
}
break
@ -203,12 +203,12 @@ extension SocketEnginePollable {
/// Send polling message.
/// Only call on emitQueue
public func sendPollMessage(_ message: String, withType type: SocketEnginePacketType, withData datas: [NSData]) {
public func sendPollMessage(_ message: String, withType type: SocketEnginePacketType, withData datas: [Data]) {
DefaultSocketLogger.Logger.log("Sending poll: %@ as type: %@", type: "SocketEnginePolling", args: message, type.rawValue)
let fixedMessage: String
if doubleEncodeUTF8 {
fixedMessage = doubleEncodeUTF8(string: message)
fixedMessage = doubleEncodeUTF8(message)
} else {
fixedMessage = message
}
@ -216,7 +216,7 @@ extension SocketEnginePollable {
postWait.append(String(type.rawValue) + fixedMessage)
for data in datas {
if case let .Right(bin) = createBinaryDataForSend(using: data) {
if case let .right(bin) = createBinaryDataForSend(using: data) {
postWait.append(bin)
}
}

View File

@ -31,77 +31,77 @@ import Foundation
var connected: Bool { get }
var connectParams: [String: AnyObject]? { get set }
var doubleEncodeUTF8: Bool { get }
var cookies: [NSHTTPCookie]? { get }
var cookies: [HTTPCookie]? { get }
var extraHeaders: [String: String]? { get }
var fastUpgrade: Bool { get }
var forcePolling: Bool { get }
var forceWebsockets: Bool { get }
var parseQueue: dispatch_queue_t { get }
var parseQueue: DispatchQueue { get }
var polling: Bool { get }
var probing: Bool { get }
var emitQueue: dispatch_queue_t { get }
var handleQueue: dispatch_queue_t { get }
var emitQueue: DispatchQueue { get }
var handleQueue: DispatchQueue { get }
var sid: String { get }
var socketPath: String { get }
var urlPolling: NSURL { get }
var urlWebSocket: NSURL { get }
var urlPolling: URL { get }
var urlWebSocket: URL { get }
var websocket: Bool { get }
var ws: WebSocket? { get }
init(client: SocketEngineClient, url: NSURL, options: NSDictionary?)
init(client: SocketEngineClient, url: URL, options: NSDictionary?)
func connect()
func didError(error: String)
func disconnect(reason: String)
func didError(_ error: String)
func disconnect(_ reason: String)
func doFastUpgrade()
func flushWaitingForPostToWebSocket()
func parseEngineData(_ data: NSData)
func parseEngineData(_ data: Data)
func parseEngineMessage(_ message: String, fromPolling: Bool)
func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [NSData])
func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data])
}
extension SocketEngineSpec {
var urlPollingWithSid: NSURL {
let com = NSURLComponents(url: urlPolling, resolvingAgainstBaseURL: false)!
var urlPollingWithSid: URL {
var com = URLComponents(url: urlPolling, resolvingAgainstBaseURL: false)!
com.percentEncodedQuery = com.percentEncodedQuery! + "&sid=\(sid.urlEncode()!)"
return com.url!
}
var urlWebSocketWithSid: NSURL {
let com = NSURLComponents(url: urlWebSocket, resolvingAgainstBaseURL: false)!
var urlWebSocketWithSid: URL {
var com = URLComponents(url: urlWebSocket, resolvingAgainstBaseURL: false)!
com.percentEncodedQuery = com.percentEncodedQuery! + (sid == "" ? "" : "&sid=\(sid.urlEncode()!)")
return com.url!
}
func createBinaryDataForSend(using data: NSData) -> Either<NSData, String> {
func createBinaryDataForSend(using data: Data) -> Either<Data, String> {
if websocket {
var byteArray = [UInt8](repeating: 0x4, count: 1)
let mutData = NSMutableData(bytes: &byteArray, length: 1)
mutData.append(data)
return .Left(mutData)
return .left(mutData as Data)
} else {
let str = "b4" + data.base64EncodedString(NSDataBase64EncodingOptions(rawValue: 0))
let str = "b4" + data.base64EncodedString(NSData.Base64EncodingOptions(rawValue: 0))
return .Right(str)
return .right(str)
}
}
func doubleEncodeUTF8(string: String) -> String {
if let latin1 = string.data(using: NSUTF8StringEncoding),
utf8 = NSString(data: latin1, encoding: NSISOLatin1StringEncoding) {
func doubleEncodeUTF8(_ string: String) -> String {
if let latin1 = string.data(using: String.Encoding.utf8),
utf8 = NSString(data: latin1, encoding: String.Encoding.isoLatin1.rawValue) {
return utf8 as String
} else {
return string
}
}
func fixDoubleUTF8(string: String) -> String {
if let utf8 = string.data(using: NSISOLatin1StringEncoding),
latin1 = NSString(data: utf8, encoding: NSUTF8StringEncoding) {
func fixDoubleUTF8(_ string: String) -> String {
if let utf8 = string.data(using: String.Encoding.isoLatin1),
latin1 = NSString(data: utf8, encoding: String.Encoding.utf8.rawValue) {
return latin1 as String
} else {
return string
@ -109,7 +109,7 @@ extension SocketEngineSpec {
}
/// Send an engine message (4)
func send(_ msg: String, withData datas: [NSData]) {
func send(_ msg: String, withData datas: [Data]) {
write(msg, withType: .message, withData: datas)
}
}

View File

@ -27,7 +27,7 @@ import Foundation
/// Protocol that is used to implement socket.io WebSocket support
public protocol SocketEngineWebsocket : SocketEngineSpec, WebSocketDelegate {
func sendWebSocketMessage(_ str: String, withType type: SocketEnginePacketType, withData datas: [NSData])
func sendWebSocketMessage(_ str: String, withType type: SocketEnginePacketType, withData datas: [Data])
}
// WebSocket methods
@ -40,23 +40,23 @@ extension SocketEngineWebsocket {
/// Send message on WebSockets
/// Only call on emitQueue
public func sendWebSocketMessage(_ str: String, withType type: SocketEnginePacketType, withData datas: [NSData]) {
public func sendWebSocketMessage(_ str: String, withType type: SocketEnginePacketType, withData datas: [Data]) {
DefaultSocketLogger.Logger.log("Sending ws: %@ as type: %@", type: "SocketEngine", args: str, type.rawValue)
ws?.writeString(str: "\(type.rawValue)\(str)")
ws?.writeString("\(type.rawValue)\(str)")
for data in datas {
if case let .Left(bin) = createBinaryDataForSend(using: data) {
ws?.writeData(data: bin)
if case let .left(bin) = createBinaryDataForSend(using: data) {
ws?.writeData(bin)
}
}
}
public func websocketDidReceiveMessage(socket: WebSocket, text: String) {
public func websocketDidReceiveMessage(_ socket: WebSocket, text: String) {
parseEngineMessage(text, fromPolling: false)
}
public func websocketDidReceiveData(socket: WebSocket, data: NSData) {
public func websocketDidReceiveData(_ socket: WebSocket, data: Data) {
parseEngineData(data)
}
}

View File

@ -26,10 +26,10 @@ import Foundation
struct SocketEventHandler {
let event: String
let id: NSUUID
let id: UUID
let callback: NormalCallback
func executeCallback(items: [AnyObject], withAck ack: Int, withSocket socket: SocketIOClient) {
func executeCallback(_ items: [AnyObject], withAck ack: Int, withSocket socket: SocketIOClient) {
callback(items, SocketAckEmitter(socket: socket, ackNum: ack))
}
}

View File

@ -25,7 +25,7 @@
import Foundation
public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable {
public let socketURL: NSURL
public let socketURL: URL
public private(set) var engine: SocketEngineSpec?
public private(set) var status = SocketIOClientStatus.notConnected {
@ -49,9 +49,9 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
return nsp + "#" + (engine?.sid ?? "")
}
private let emitQueue = dispatch_queue_create("com.socketio.emitQueue", DISPATCH_QUEUE_SERIAL)!
private let emitQueue = DispatchQueue(label: "com.socketio.emitQueue", attributes: DispatchQueueAttributes.serial)
private let logType = "SocketIOClient"
private let parseQueue = dispatch_queue_create("com.socketio.parseQueue", DISPATCH_QUEUE_SERIAL)!
private let parseQueue = DispatchQueue(label: "com.socketio.parseQueue", attributes: DispatchQueueAttributes.serial)
private var anyHandler: ((SocketAnyEvent) -> Void)?
private var currentReconnectAttempt = 0
@ -60,18 +60,18 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
private var reconnecting = false
private(set) var currentAck = -1
private(set) var handleQueue = dispatch_get_main_queue()!
private(set) var handleQueue = DispatchQueue.main
private(set) var reconnectAttempts = -1
var waitingPackets = [SocketPacket]()
/// Type safe way to create a new SocketIOClient. opts can be omitted
public init(socketURL: NSURL, options: Set<SocketIOClientOption> = []) {
public init(socketURL: URL, options: Set<SocketIOClientOption> = []) {
self.options = options
self.socketURL = socketURL
if socketURL.absoluteString.hasPrefix("https://") {
self.options.insertIgnore(element: .secure(true))
if ((socketURL.absoluteString?.hasPrefix("https://")) != nil) {
self.options.insertIgnore(.secure(true))
}
for option in options {
@ -97,20 +97,20 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
}
}
self.options.insertIgnore(element: .path("/socket.io/"))
self.options.insertIgnore(.path("/socket.io/"))
super.init()
}
/// Not so type safe way to create a SocketIOClient, meant for Objective-C compatiblity.
/// If using Swift it's recommended to use `init(socketURL: NSURL, options: Set<SocketIOClientOption>)`
public convenience init(socketURL: NSURL, options: NSDictionary?) {
public convenience init(socketURL: URL, options: NSDictionary?) {
self.init(socketURL: socketURL, options: options?.toSocketOptionsSet() ?? [])
}
deinit {
DefaultSocketLogger.Logger.log("Client is being released", type: logType)
engine?.disconnect(reason: "Client Deinit")
engine?.disconnect("Client Deinit")
}
private func addEngine() -> SocketEngineSpec {
@ -123,11 +123,11 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
/// Connect to the server.
public func connect() {
connect(timeoutAfter: 0, handleWith: nil)
connect(0, handleWith: nil)
}
/// Connect to the server. If we aren't connected after timeoutAfter, call handler
public func connect(timeoutAfter: Int, handleWith handler: (() -> Void)?) {
public func connect(_ timeoutAfter: Int, handleWith handler: (() -> Void)?) {
assert(timeoutAfter >= 0, "Invalid timeout: \(timeoutAfter)")
guard status != .connected else {
@ -145,30 +145,30 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
guard timeoutAfter != 0 else { return }
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeoutAfter) * Int64(NSEC_PER_SEC))
let time = DispatchTime.now() + Double(Int64(timeoutAfter) * Int64(NSEC_PER_SEC)) / Double(NSEC_PER_SEC)
dispatch_after(time, handleQueue) {[weak self] in
handleQueue.after(when: time) {[weak self] in
if let this = self where this.status != .connected && this.status != .disconnected {
this.status = .disconnected
this.engine?.disconnect(reason: "Connect timeout")
this.engine?.disconnect("Connect timeout")
handler?()
}
}
}
private func createOnAck(items: [AnyObject]) -> OnAckCallback {
private func createOnAck(_ items: [AnyObject]) -> OnAckCallback {
currentAck += 1
return {[weak self, ack = currentAck] timeout, callback in
if let this = self {
this.ackHandlers.addAck(ack, callback: callback)
this._emit(data: items, ack: ack)
this._emit(items, ack: ack)
if timeout != 0 {
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeout * NSEC_PER_SEC))
let time = DispatchTime.now() + Double(Int64(timeout * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)
dispatch_after(time, this.handleQueue) {
this.handleQueue.after(when: time) {
this.ackHandlers.timeoutAck(ack)
}
}
@ -185,7 +185,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
handleEvent("connect", data: [], isInternalMessage: false)
}
func didDisconnect(reason: String) {
func didDisconnect(_ reason: String) {
guard status != .disconnected else { return }
DefaultSocketLogger.Logger.log("Disconnected: %@", type: logType, args: reason)
@ -193,7 +193,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
status = .disconnected
// Make sure the engine is actually dead.
engine?.disconnect(reason: reason)
engine?.disconnect(reason)
handleEvent("disconnect", data: [reason as AnyObject], isInternalMessage: true)
}
@ -203,12 +203,12 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
DefaultSocketLogger.Logger.log("Closing socket", type: logType)
didDisconnect(reason: "Disconnect")
didDisconnect("Disconnect")
}
/// Send a message to the server
public func emit(_ event: String, _ items: SocketData...) {
emit(event, with: socketDataToAnyObject(data: items))
emit(event, with: socketDataToAnyObject(items))
}
/// Same as emit, but meant for Objective-C
@ -218,28 +218,28 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
return
}
_emit(data: [event as AnyObject] + items)
_emit([event as AnyObject] + items)
}
/// 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: SocketData...) -> OnAckCallback {
return emitWithAck(event, with: socketDataToAnyObject(data: items))
return emitWithAck(event, with: socketDataToAnyObject(items))
}
/// Same as emitWithAck, but for Objective-C
public func emitWithAck(_ event: String, with items: [AnyObject]) -> OnAckCallback {
return createOnAck(items: [event as AnyObject] + items)
return createOnAck([event as AnyObject] + items)
}
private func _emit(data: [AnyObject], ack: Int? = nil) {
dispatch_async(emitQueue) {
private func _emit(_ data: [AnyObject], ack: Int? = nil) {
emitQueue.async {
guard self.status == .connected else {
self.handleEvent("error", data: ["Tried emitting when not connected"], isInternalMessage: true)
return
}
let packet = SocketPacket.packetFromEmit(items: data, id: ack ?? -1, nsp: self.nsp, ack: false)
let packet = SocketPacket.packetFromEmit(data, id: ack ?? -1, nsp: self.nsp, ack: false)
let str = packet.packetString
DefaultSocketLogger.Logger.log("Emitting: %@", type: self.logType, args: str)
@ -250,9 +250,9 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
// If the server wants to know that the client received data
func emitAck(_ ack: Int, with items: [AnyObject]) {
dispatch_async(emitQueue) {
emitQueue.async {
if self.status == .connected {
let packet = SocketPacket.packetFromEmit(items: items, id: ack ?? -1, nsp: self.nsp, ack: true)
let packet = SocketPacket.packetFromEmit(items, id: ack ?? -1, nsp: self.nsp, ack: true)
let str = packet.packetString
DefaultSocketLogger.Logger.log("Emitting Ack: %@", type: self.logType, args: str)
@ -262,7 +262,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
}
}
public func engineDidClose(reason: String) {
public func engineDidClose(_ reason: String) {
waitingPackets.removeAll()
if status != .disconnected {
@ -270,21 +270,21 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
}
if status == .disconnected || !reconnects {
didDisconnect(reason: reason)
didDisconnect(reason)
} else if !reconnecting {
reconnecting = true
tryReconnect(reason: reason)
tryReconnect(reason)
}
}
/// error
public func engineDidError(reason: String) {
public func engineDidError(_ reason: String) {
DefaultSocketLogger.Logger.error("%@", type: logType, args: reason)
handleEvent("error", data: [reason as AnyObject], isInternalMessage: true)
}
public func engineDidOpen(reason: String) {
public func engineDidOpen(_ reason: String) {
DefaultSocketLogger.Logger.log(reason, type: "SocketEngineClient")
}
@ -303,11 +303,11 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
DefaultSocketLogger.Logger.log("Handling event: %@ with data: %@", type: logType, args: event, data ?? "")
dispatch_async(handleQueue) {
handleQueue.async {
self.anyHandler?(SocketAnyEvent(event: event, items: data))
for handler in self.handlers where handler.event == event {
handler.executeCallback(items: data, withAck: ack, withSocket: self)
handler.executeCallback(data, withAck: ack, withSocket: self)
}
}
}
@ -338,7 +338,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
}
/// Removes a handler with the specified UUID gotten from an `on` or `once`
public func off(id: NSUUID) {
public func off(id: UUID) {
DefaultSocketLogger.Logger.log("Removing handler with id: %@", type: logType, args: id)
handlers = handlers.filter({ $0.id != id })
@ -347,22 +347,22 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
/// Adds a handler for an event.
/// Returns: A unique id for the handler
@discardableResult
public func on(_ event: String, callback: NormalCallback) -> NSUUID {
public func on(_ event: String, callback: NormalCallback) -> UUID {
DefaultSocketLogger.Logger.log("Adding handler for event: %@", type: logType, args: event)
let handler = SocketEventHandler(event: event, id: NSUUID(), callback: callback)
let handler = SocketEventHandler(event: event, id: UUID(), callback: callback)
handlers.append(handler)
return handler.id
return handler.id as UUID
}
/// Adds a single-use handler for an event.
/// Returns: A unique id for the handler
@discardableResult
public func once(event: String, callback: NormalCallback) -> NSUUID {
public func once(_ event: String, callback: NormalCallback) -> UUID {
DefaultSocketLogger.Logger.log("Adding once handler for event: %@", type: logType, args: event)
let id = NSUUID()
let id = UUID()
let handler = SocketEventHandler(event: event, id: id) {[weak self] data, ack in
guard let this = self else { return }
@ -372,24 +372,24 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
handlers.append(handler)
return handler.id
return handler.id as UUID
}
/// Adds a handler that will be called on every event.
public func onAny(handler: (SocketAnyEvent) -> Void) {
public func onAny(_ handler: (SocketAnyEvent) -> Void) {
anyHandler = handler
}
public func parseEngineMessage(_ msg: String) {
DefaultSocketLogger.Logger.log("Should parse message: %@", type: "SocketIOClient", args: msg)
dispatch_async(parseQueue) {
parseQueue.async {
self.parseSocketMessage(msg)
}
}
public func parseEngineBinaryData(_ data: NSData) {
dispatch_async(parseQueue) {
public func parseEngineBinaryData(_ data: Data) {
parseQueue.async {
self.parseBinaryData(data)
}
}
@ -398,7 +398,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
public func reconnect() {
guard !reconnecting else { return }
engine?.disconnect(reason: "manual reconnect")
engine?.disconnect("manual reconnect")
}
/// Removes all handlers.
@ -407,11 +407,11 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
handlers.removeAll(keepingCapacity: false)
}
func socketDataToAnyObject(data: [SocketData]) -> [AnyObject] {
func socketDataToAnyObject(_ data: [SocketData]) -> [AnyObject] {
return data.flatMap({$0 as? AnyObject})
}
private func tryReconnect(reason: String) {
private func tryReconnect(_ reason: String) {
if reconnecting {
DefaultSocketLogger.Logger.log("Starting reconnect", type: logType)
handleEvent("reconnect", data: [reason as AnyObject], isInternalMessage: true)
@ -426,7 +426,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
}
if reconnectAttempts != -1 && currentReconnectAttempt + 1 > reconnectAttempts || !reconnects {
return didDisconnect(reason: "Reconnect Failed")
return didDisconnect("Reconnect Failed")
}
DefaultSocketLogger.Logger.log("Trying to reconnect", type: logType)
@ -436,9 +436,9 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
currentReconnectAttempt += 1
connect()
let dispatchAfter = dispatch_time(DISPATCH_TIME_NOW, Int64(UInt64(reconnectWait) * NSEC_PER_SEC))
let dispatchAfter = DispatchTime.now() + Double(Int64(UInt64(reconnectWait) * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)
dispatch_after(dispatchAfter, dispatch_get_main_queue(), _tryReconnect)
DispatchQueue.main.after(when: dispatchAfter, execute: _tryReconnect)
}
}
@ -452,11 +452,11 @@ extension SocketIOClient {
status = .connected
}
func setTestEngine(engine: SocketEngineSpec?) {
func setTestEngine(_ engine: SocketEngineSpec?) {
self.engine = engine
}
func emitTest(event: String, _ data: AnyObject...) {
self._emit(data: [event as AnyObject] + data)
func emitTest(_ event: String, _ data: AnyObject...) {
self._emit([event as AnyObject] + data)
}
}

View File

@ -30,13 +30,13 @@ protocol ClientOption : CustomStringConvertible, Hashable {
public enum SocketIOClientOption : ClientOption {
case connectParams([String: AnyObject])
case cookies([NSHTTPCookie])
case cookies([HTTPCookie])
case doubleEncodeUTF8(Bool)
case extraHeaders([String: String])
case forceNew(Bool)
case forcePolling(Bool)
case forceWebsockets(Bool)
case handleQueue(dispatch_queue_t)
case handleQueue(DispatchQueue)
case log(Bool)
case logger(SocketLogger)
case nsp(String)
@ -47,7 +47,7 @@ public enum SocketIOClientOption : ClientOption {
case secure(Bool)
case security(SSLSecurity)
case selfSigned(Bool)
case sessionDelegate(NSURLSessionDelegate)
case sessionDelegate(URLSessionDelegate)
case voipEnabled(Bool)
public var description: String {
@ -158,7 +158,7 @@ public func ==(lhs: SocketIOClientOption, rhs: SocketIOClientOption) -> Bool {
}
extension Set where Element : ClientOption {
mutating func insertIgnore(element: Element) {
mutating func insertIgnore(_ element: Element) {
if !contains(element) {
insert(element)
}
@ -166,11 +166,11 @@ extension Set where Element : ClientOption {
}
extension NSDictionary {
private static func keyValueToSocketIOClientOption(key: String, value: AnyObject) -> SocketIOClientOption? {
private static func keyValueToSocketIOClientOption(_ key: String, value: AnyObject) -> SocketIOClientOption? {
switch (key, value) {
case let ("connectParams", params as [String: AnyObject]):
return .connectParams(params)
case let ("cookies", cookies as [NSHTTPCookie]):
case let ("cookies", cookies as [HTTPCookie]):
return .cookies(cookies)
case let ("doubleEncodeUTF8", encode as Bool):
return .doubleEncodeUTF8(encode)
@ -182,7 +182,7 @@ extension NSDictionary {
return .forcePolling(force)
case let ("forceWebsockets", force as Bool):
return .forceWebsockets(force)
case let ("handleQueue", queue as dispatch_queue_t):
case let ("handleQueue", queue as DispatchQueue):
return .handleQueue(queue)
case let ("log", log as Bool):
return .log(log)
@ -204,7 +204,7 @@ extension NSDictionary {
return .security(security)
case let ("selfSigned", selfSigned as Bool):
return .selfSigned(selfSigned)
case let ("sessionDelegate", delegate as NSURLSessionDelegate):
case let ("sessionDelegate", delegate as URLSessionDelegate):
return .sessionDelegate(delegate)
case let ("voipEnabled", enable as Bool):
return .voipEnabled(enable)
@ -217,8 +217,8 @@ extension NSDictionary {
var options = Set<SocketIOClientOption>()
for (rawKey, value) in self {
if let key = rawKey as? String, opt = NSDictionary.keyValueToSocketIOClientOption(key: key, value: value) {
options.insertIgnore(element: opt)
if let key = rawKey as? String, opt = NSDictionary.keyValueToSocketIOClientOption(key, value: value) {
options.insertIgnore(opt)
}
}

View File

@ -27,15 +27,15 @@ protocol SocketIOClientSpec : class {
var waitingPackets: [SocketPacket] { get set }
func didConnect()
func didDisconnect(reason: String)
func didError(reason: String)
func didDisconnect(_ reason: String)
func didError(_ reason: String)
func handleAck(_ ack: Int, data: [AnyObject])
func handleEvent(_ event: String, data: [AnyObject], isInternalMessage: Bool, withAck ack: Int)
func joinNamespace(_ namespace: String)
}
extension SocketIOClientSpec {
func didError(reason: String) {
func didError(_ reason: String) {
DefaultSocketLogger.Logger.error("%@", type: "SocketIOClient", args: reason)
handleEvent("error", data: [reason as AnyObject], isInternalMessage: true, withAck: -1)

View File

@ -35,18 +35,18 @@ struct SocketPacket {
let type: PacketType
enum PacketType: Int {
case Connect, Disconnect, Event, Ack, Error, BinaryEvent, BinaryAck
case connect, disconnect, event, ack, error, binaryEvent, binaryAck
}
var args: [AnyObject] {
if type == .Event || type == .BinaryEvent && data.count != 0 {
if type == .event || type == .binaryEvent && data.count != 0 {
return Array(data.dropFirst())
} else {
return data
}
}
var binary: [NSData]
var binary: [Data]
var data: [AnyObject]
var description: String {
return "SocketPacket {type: \(String(type.rawValue)); data: " +
@ -62,7 +62,7 @@ struct SocketPacket {
}
init(type: PacketType, data: [AnyObject] = [AnyObject](), id: Int = -1,
nsp: String, placeholders: Int = 0, binary: [NSData] = [NSData]()) {
nsp: String, placeholders: Int = 0, binary: [Data] = [Data]()) {
self.data = data
self.id = id
self.nsp = nsp
@ -71,7 +71,7 @@ struct SocketPacket {
self.binary = binary
}
mutating func addData(_ data: NSData) -> Bool {
mutating func addData(_ data: Data) -> Bool {
if placeholders == binary.count {
return true
}
@ -94,9 +94,9 @@ struct SocketPacket {
}
do {
let jsonSend = try NSJSONSerialization.data(withJSONObject: data as AnyObject,
options: NSJSONWritingOptions(rawValue: 0))
guard let jsonString = String(data: jsonSend, encoding: NSUTF8StringEncoding) else {
let jsonSend = try JSONSerialization.data(withJSONObject: data as AnyObject,
options: JSONSerialization.WritingOptions(rawValue: 0))
guard let jsonString = String(data: jsonSend, encoding: String.Encoding.utf8) else {
return message + "[]"
}
@ -117,7 +117,7 @@ struct SocketPacket {
let nspString: String
let idString: String
if type == .BinaryEvent || type == .BinaryAck {
if type == .binaryEvent || type == .binaryAck {
binaryCountString = typeString + String(binary.count) + "-"
} else {
binaryCountString = typeString
@ -172,19 +172,19 @@ extension SocketPacket {
private static func findType(_ binCount: Int, ack: Bool) -> PacketType {
switch binCount {
case 0 where !ack:
return .Event
return .event
case 0 where ack:
return .Ack
return .ack
case _ where !ack:
return .BinaryEvent
return .binaryEvent
case _ where ack:
return .BinaryAck
return .binaryAck
default:
return .Error
return .error
}
}
static func packetFromEmit(items: [AnyObject], id: Int, nsp: String, ack: Bool) -> SocketPacket {
static func packetFromEmit(_ items: [AnyObject], id: Int, nsp: String, ack: Bool) -> SocketPacket {
let (parsedData, binary) = deconstructData(items)
let packet = SocketPacket(type: findType(binary.count, ack: ack), data: parsedData,
id: id, nsp: nsp, binary: binary)
@ -195,11 +195,11 @@ extension SocketPacket {
private extension SocketPacket {
// Recursive function that looks for NSData in collections
static func shred(_ data: AnyObject, binary: inout [NSData]) -> AnyObject {
static func shred(_ data: AnyObject, binary: inout [Data]) -> AnyObject {
let placeholder = ["_placeholder": true, "num": binary.count as AnyObject]
switch data {
case let bin as NSData:
case let bin as Data:
binary.append(bin)
return placeholder as AnyObject
case let arr as [AnyObject]:
@ -216,8 +216,8 @@ private extension SocketPacket {
// Removes binary data from emit data
// Returns a type containing the de-binaryed data and the binary
static func deconstructData(_ data: [AnyObject]) -> ([AnyObject], [NSData]) {
var binary = [NSData]()
static func deconstructData(_ data: [AnyObject]) -> ([AnyObject], [Data]) {
var binary = [Data]()
return (data.map({shred($0, binary: &binary)}), binary)
}

View File

@ -23,7 +23,7 @@
import Foundation
protocol SocketParsable : SocketIOClientSpec {
func parseBinaryData(_ data: NSData)
func parseBinaryData(_ data: Data)
func parseSocketMessage(_ message: String)
}
@ -42,19 +42,19 @@ extension SocketParsable {
private func handlePacket(_ pack: SocketPacket) {
switch pack.type {
case .Event where isCorrectNamespace(pack.nsp):
case .event where isCorrectNamespace(pack.nsp):
handleEvent(pack.event, data: pack.args, isInternalMessage: false, withAck: pack.id)
case .Ack where isCorrectNamespace(pack.nsp):
case .ack where isCorrectNamespace(pack.nsp):
handleAck(pack.id, data: pack.data)
case .BinaryEvent where isCorrectNamespace(pack.nsp):
case .binaryEvent where isCorrectNamespace(pack.nsp):
waitingPackets.append(pack)
case .BinaryAck where isCorrectNamespace(pack.nsp):
case .binaryAck where isCorrectNamespace(pack.nsp):
waitingPackets.append(pack)
case .Connect:
case .connect:
handleConnect(pack)
case .Disconnect:
didDisconnect(reason: "Got Disconnect")
case .Error:
case .disconnect:
didDisconnect("Got Disconnect")
case .error:
handleEvent("error", data: pack.data, isInternalMessage: true, withAck: pack.id)
default:
DefaultSocketLogger.Logger.log("Got invalid packet: %@", type: "SocketParser", args: pack.description)
@ -65,22 +65,22 @@ extension SocketParsable {
func parseString(_ message: String) -> Either<String, SocketPacket> {
var parser = SocketStringReader(message: message)
guard let type = SocketPacket.PacketType(rawValue: Int(parser.read(length: 1)) ?? -1) else {
return .Left("Invalid packet type")
guard let type = SocketPacket.PacketType(rawValue: Int(parser.read(1)) ?? -1) else {
return .left("Invalid packet type")
}
if !parser.hasNext {
return .Right(SocketPacket(type: type, nsp: "/"))
return .right(SocketPacket(type: type, nsp: "/"))
}
var namespace = "/"
var placeholders = -1
if type == .BinaryEvent || type == .BinaryAck {
if type == .binaryEvent || type == .binaryAck {
if let holders = Int(parser.readUntilStringOccurence("-")) {
placeholders = holders
} else {
return .Left("Invalid packet")
return .left("Invalid packet")
}
}
@ -89,53 +89,53 @@ extension SocketParsable {
}
if !parser.hasNext {
return .Right(SocketPacket(type: type, nsp: namespace, placeholders: placeholders))
return .right(SocketPacket(type: type, nsp: namespace, placeholders: placeholders))
}
var idString = ""
if type == .Error {
parser.advance(by: -1)
if type == .error {
parser.advance(-1)
} else {
while parser.hasNext {
if let int = Int(parser.read(length: 1)) {
if let int = Int(parser.read(1)) {
idString += String(int)
} else {
parser.advance(by: -2)
parser.advance(-2)
break
}
}
}
let d = message[parser.advance(by: 1)..<message.endIndex]
let d = message[parser.advance(1)..<message.endIndex]
switch parseData(d) {
case let .Left(err):
case let .left(err):
// Errors aren't always enclosed in an array
if case let .Right(data) = parseData("\([d as AnyObject])") {
return .Right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1,
if case let .right(data) = parseData("\([d as AnyObject])") {
return .right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1,
nsp: namespace, placeholders: placeholders))
} else {
return .Left(err)
return .left(err)
}
case let .Right(data):
return .Right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1,
case let .right(data):
return .right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1,
nsp: namespace, placeholders: placeholders))
}
}
// Parses data for events
private func parseData(_ data: String) -> Either<String, [AnyObject]> {
let stringData = data.data(using: NSUTF8StringEncoding, allowLossyConversion: false)
let stringData = data.data(using: String.Encoding.utf8, allowLossyConversion: false)
do {
if let arr = try NSJSONSerialization.jsonObject(with: stringData!,
options: NSJSONReadingOptions.mutableContainers) as? [AnyObject] {
return .Right(arr)
if let arr = try JSONSerialization.jsonObject(with: stringData!,
options: JSONSerialization.ReadingOptions.mutableContainers) as? [AnyObject] {
return .right(arr)
} else {
return .Left("Expected data array")
return .left("Expected data array")
}
} catch {
return .Left("Error parsing data for packet")
return .left("Error parsing data for packet")
}
}
@ -146,15 +146,15 @@ extension SocketParsable {
DefaultSocketLogger.Logger.log("Parsing %@", type: "SocketParser", args: message)
switch parseString(message) {
case let .Left(err):
case let .left(err):
DefaultSocketLogger.Logger.error("\(err): %@", type: "SocketParser", args: message)
case let .Right(pack):
case let .right(pack):
DefaultSocketLogger.Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description)
handlePacket(pack)
}
}
func parseBinaryData(_ data: NSData) {
func parseBinaryData(_ data: Data) {
guard !waitingPackets.isEmpty else {
DefaultSocketLogger.Logger.error("Got data when not remaking packet", type: "SocketParser")
return
@ -165,7 +165,7 @@ extension SocketParsable {
let packet = waitingPackets.removeLast()
if packet.type != .BinaryAck {
if packet.type != .binaryAck {
handleEvent(packet.event, data: packet.args ?? [],
isInternalMessage: false, withAck: packet.id)
} else {

View File

@ -39,15 +39,15 @@ struct SocketStringReader {
}
@discardableResult
mutating func advance(by: Int) -> String.Index {
mutating func advance(_ by: Int) -> String.Index {
currentIndex = message.characters.index(currentIndex, offsetBy: by)
return currentIndex
}
mutating func read(length: Int) -> String {
mutating func read(_ length: Int) -> String {
let readString = message[currentIndex..<message.characters.index(currentIndex, offsetBy: length)]
advance(by: length)
advance(length)
return readString
}
@ -60,12 +60,12 @@ struct SocketStringReader {
return substring
}
advance(by: message.characters.distance(from: message.characters.startIndex, to: foundRange.lowerBound) + 1)
advance(message.characters.distance(from: message.characters.startIndex, to: foundRange.lowerBound) + 1)
return substring.substring(to: foundRange.lowerBound)
}
mutating func readUntilEnd() -> String {
return read(length: message.characters.distance(from: currentIndex, to: message.endIndex))
return read(message.characters.distance(from: currentIndex, to: message.endIndex))
}
}

View File

@ -32,7 +32,7 @@ extension Dictionary : SocketData {}
extension Double : SocketData {}
extension Int : SocketData {}
extension NSArray : SocketData {}
extension NSData : SocketData {}
extension Data : SocketData {}
extension NSDictionary : SocketData {}
extension NSString : SocketData {}
extension NSNull : SocketData {}
@ -42,10 +42,10 @@ public typealias AckCallback = ([AnyObject]) -> Void
public typealias NormalCallback = ([AnyObject], SocketAckEmitter) -> Void
public typealias OnAckCallback = (timeoutAfter: UInt64, callback: AckCallback) -> Void
typealias Probe = (msg: String, type: SocketEnginePacketType, data: [NSData])
typealias Probe = (msg: String, type: SocketEnginePacketType, data: [Data])
typealias ProbeWaitQueue = [Probe]
enum Either<E, V> {
case Left(E)
case Right(V)
case left(E)
case right(V)
}

View File

@ -24,7 +24,7 @@ import Foundation
import Security
public class SSLCert : NSObject {
var certData: NSData?
var certData: Data?
var key: SecKey?
/**
@ -34,7 +34,7 @@ public class SSLCert : NSObject {
- returns: a representation security object to be used with
*/
public init(data: NSData) {
public init(data: Data) {
self.certData = data
}
@ -54,7 +54,7 @@ public class SSLSecurity : NSObject {
public var validatedDN = true //should the domain name be validated?
var isReady = false //is the key processing done?
var certificates: [NSData]? //the certificates
var certificates: [Data]? //the certificates
var pubKeys: [SecKey]? //the public keys
var usePublicKeys = false //use public keys or certificate validation?
@ -66,12 +66,12 @@ public class SSLSecurity : NSObject {
- returns: a representation security object to be used with
*/
public convenience init(usePublicKeys: Bool = false) {
let paths = NSBundle.main().pathsForResources(ofType: "cer", inDirectory: ".")
let paths = Bundle.main().pathsForResources(ofType: "cer", inDirectory: ".")
let certs = paths.reduce([SSLCert]()) { (certs: [SSLCert], path: String) -> [SSLCert] in
var certs = certs
if let data = NSData(contentsOfFile: path) {
certs.append(SSLCert(data: data))
certs.append(SSLCert(data: data as Data))
}
return certs
}
@ -93,11 +93,11 @@ public class SSLSecurity : NSObject {
self.usePublicKeys = usePublicKeys
if self.usePublicKeys {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)) {
DispatchQueue.global(attributes: DispatchQueue.GlobalAttributes.qosDefault).async {
let pubKeys = certs.reduce([SecKey]()) { (pubKeys: [SecKey], cert: SSLCert) -> [SecKey] in
var pubKeys = pubKeys
if let data = cert.certData where cert.key == nil {
cert.key = self.extractPublicKey(data: data)
cert.key = self.extractPublicKey(data)
}
if let key = cert.key {
pubKeys.append(key)
@ -109,7 +109,7 @@ public class SSLSecurity : NSObject {
self.isReady = true
}
} else {
let certificates = certs.reduce([NSData]()) { (certificates: [NSData], cert: SSLCert) -> [NSData] in
let certificates = certs.reduce([Data]()) { (certificates: [Data], cert: SSLCert) -> [Data] in
var certificates = certificates
if let data = cert.certData {
certificates.append(data)
@ -129,7 +129,7 @@ public class SSLSecurity : NSObject {
- returns: if the key was successfully validated
*/
public func isValid(trust: SecTrust, domain: String?) -> Bool {
public func isValid(_ trust: SecTrust, domain: String?) -> Bool {
var tries = 0
while(!self.isReady) {
@ -141,14 +141,14 @@ public class SSLSecurity : NSObject {
}
var policy: SecPolicy
if self.validatedDN {
policy = SecPolicyCreateSSL(true, domain)
policy = SecPolicyCreateSSL(true, domain)!
} else {
policy = SecPolicyCreateBasicX509()
policy = SecPolicyCreateBasicX509()!
}
SecTrustSetPolicies(trust,policy)
if self.usePublicKeys {
if let keys = self.pubKeys {
let serverPubKeys = publicKeyChainForTrust(trust: trust)
let serverPubKeys = publicKeyChainForTrust(trust)
for serverKey in serverPubKeys as [AnyObject] {
for key in keys as [AnyObject] {
if serverKey.isEqual(key) {
@ -158,16 +158,16 @@ public class SSLSecurity : NSObject {
}
}
} else if let certs = self.certificates {
let serverCerts = certificateChainForTrust(trust: trust)
let serverCerts = certificateChainForTrust(trust)
var collect = [SecCertificate]()
for cert in certs {
collect.append(SecCertificateCreateWithData(nil,cert)!)
}
SecTrustSetAnchorCertificates(trust,collect)
var result: SecTrustResultType = 0
var result = SecTrustResultType(rawValue: 0)!
SecTrustEvaluate(trust,&result)
let r = Int(result)
if r == kSecTrustResultUnspecified || r == kSecTrustResultProceed {
let r = Int(result.rawValue)
if r == Int(SecTrustResultType.unspecified.rawValue) || r == Int(SecTrustResultType.proceed.rawValue) {
var trustedCount = 0
for serverCert in serverCerts {
for cert in certs {
@ -192,10 +192,10 @@ public class SSLSecurity : NSObject {
- returns: a public key
*/
func extractPublicKey(data: NSData) -> SecKey? {
func extractPublicKey(_ data: Data) -> SecKey? {
guard let cert = SecCertificateCreateWithData(nil, data) else { return nil }
return extractPublicKeyFromCert(cert: cert, policy: SecPolicyCreateBasicX509())
return extractPublicKeyFromCert(cert, policy: SecPolicyCreateBasicX509()!)
}
/**
@ -205,13 +205,13 @@ public class SSLSecurity : NSObject {
- returns: a public key
*/
func extractPublicKeyFromCert(cert: SecCertificate, policy: SecPolicy) -> SecKey? {
func extractPublicKeyFromCert(_ cert: SecCertificate, policy: SecPolicy) -> SecKey? {
var possibleTrust: SecTrust?
SecTrustCreateWithCertificates(cert, policy, &possibleTrust)
guard let trust = possibleTrust else { return nil }
var result: SecTrustResultType = 0
var result = SecTrustResultType(rawValue: 0)!
SecTrustEvaluate(trust, &result)
return SecTrustCopyPublicKey(trust)
}
@ -223,11 +223,11 @@ public class SSLSecurity : NSObject {
- returns: the certificate chain for the trust
*/
func certificateChainForTrust(trust: SecTrust) -> [NSData] {
let certificates = (0..<SecTrustGetCertificateCount(trust)).reduce([NSData]()) { (certificates: [NSData], index: Int) -> [NSData] in
func certificateChainForTrust(_ trust: SecTrust) -> [Data] {
let certificates = (0..<SecTrustGetCertificateCount(trust)).reduce([Data]()) { (certificates: [Data], index: Int) -> [Data] in
var certificates = certificates
let cert = SecTrustGetCertificateAtIndex(trust, index)
certificates.append(SecCertificateCopyData(cert!))
certificates.append(SecCertificateCopyData(cert!) as Data)
return certificates
}
@ -241,12 +241,12 @@ public class SSLSecurity : NSObject {
- returns: the public keys from the certifcate chain for the trust
*/
func publicKeyChainForTrust(trust: SecTrust) -> [SecKey] {
func publicKeyChainForTrust(_ trust: SecTrust) -> [SecKey] {
let policy = SecPolicyCreateBasicX509()
let keys = (0..<SecTrustGetCertificateCount(trust)).reduce([SecKey]()) { (keys: [SecKey], index: Int) -> [SecKey] in
var keys = keys
let cert = SecTrustGetCertificateAtIndex(trust, index)
if let key = extractPublicKeyFromCert(cert: cert!, policy: policy) {
if let key = extractPublicKeyFromCert(cert!, policy: policy!) {
keys.append(key)
}
@ -257,4 +257,4 @@ public class SSLSecurity : NSObject {
}
}
}

View File

@ -28,40 +28,40 @@ public let WebsocketDidDisconnectNotification = "WebsocketDidDisconnectNotificat
public let WebsocketDisconnectionErrorKeyName = "WebsocketDisconnectionErrorKeyName"
public protocol WebSocketDelegate: class {
func websocketDidConnect(socket: WebSocket)
func websocketDidDisconnect(socket: WebSocket, error: NSError?)
func websocketDidReceiveMessage(socket: WebSocket, text: String)
func websocketDidReceiveData(socket: WebSocket, data: NSData)
func websocketDidConnect(_ socket: WebSocket)
func websocketDidDisconnect(_ socket: WebSocket, error: NSError?)
func websocketDidReceiveMessage(_ socket: WebSocket, text: String)
func websocketDidReceiveData(_ socket: WebSocket, data: Data)
}
public protocol WebSocketPongDelegate: class {
func websocketDidReceivePong(socket: WebSocket)
func websocketDidReceivePong(_ socket: WebSocket)
}
public class WebSocket : NSObject, NSStreamDelegate {
public class WebSocket : NSObject, StreamDelegate {
enum OpCode : UInt8 {
case ContinueFrame = 0x0
case TextFrame = 0x1
case BinaryFrame = 0x2
case continueFrame = 0x0
case textFrame = 0x1
case binaryFrame = 0x2
//3-7 are reserved.
case ConnectionClose = 0x8
case Ping = 0x9
case Pong = 0xA
case connectionClose = 0x8
case ping = 0x9
case pong = 0xA
//B-F reserved.
}
public enum CloseCode : UInt16 {
case Normal = 1000
case GoingAway = 1001
case ProtocolError = 1002
case ProtocolUnhandledType = 1003
case normal = 1000
case goingAway = 1001
case protocolError = 1002
case protocolUnhandledType = 1003
// 1004 reserved.
case NoStatusReceived = 1005
case noStatusReceived = 1005
//1006 reserved.
case Encoding = 1007
case PolicyViolated = 1008
case MessageTooBig = 1009
case encoding = 1007
case policyViolated = 1008
case messageTooBig = 1009
}
#if swift(>=3)
@ -71,11 +71,11 @@ public class WebSocket : NSObject, NSStreamDelegate {
enum InternalErrorCode : UInt16 {
// 0-999 WebSocket status codes not used
case OutputStreamWriteError = 1
case outputStreamWriteError = 1
}
//Where the callback is executed. It defaults to the main UI thread queue.
public var queue = dispatch_get_main_queue()
public var queue = DispatchQueue.main
var optionalProtocols : [String]?
//Constant Values.
@ -100,7 +100,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
class WSResponse {
var isFin = false
var code: OpCode = .ContinueFrame
var code: OpCode = .continueFrame
var bytesLeft = 0
var frameCount = 0
var buffer: NSMutableData?
@ -111,7 +111,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
public var onConnect: ((Void) -> Void)?
public var onDisconnect: ((NSError?) -> Void)?
public var onText: ((String) -> Void)?
public var onData: ((NSData) -> Void)?
public var onData: ((Data) -> Void)?
public var onPong: ((Void) -> Void)?
public var headers = [String: String]()
public var voipEnabled = false
@ -123,21 +123,21 @@ public class WebSocket : NSObject, NSStreamDelegate {
public var isConnected :Bool {
return connected
}
public var currentURL: NSURL {return url}
private var url: NSURL
private var inputStream: NSInputStream?
public var currentURL: URL {return url}
private var url: URL
private var inputStream: InputStream?
private var outputStream: NSOutputStream?
private var connected = false
private var isCreated = false
private var writeQueue = NSOperationQueue()
private var writeQueue = OperationQueue()
private var readStack = [WSResponse]()
private var inputQueue = [NSData]()
private var fragBuffer: NSData?
private var inputQueue = [Data]()
private var fragBuffer: Data?
private var certValidated = false
private var didDisconnect = false
private var readyToWrite = false
private let mutex = NSLock()
private let notificationCenter = NSNotificationCenter.default()
private let mutex = Lock()
private let notificationCenter = NotificationCenter.default()
private var canDispatch: Bool {
mutex.lock()
let canWork = readyToWrite
@ -145,10 +145,10 @@ public class WebSocket : NSObject, NSStreamDelegate {
return canWork
}
//the shared processing queue used for all websocket
private static let sharedWorkQueue = dispatch_queue_create("com.vluxe.starscream.websocket", DISPATCH_QUEUE_SERIAL)
private static let sharedWorkQueue = DispatchQueue(label: "com.vluxe.starscream.websocket", attributes: DispatchQueueAttributes.serial)
//used for setting protocols.
public init(url: NSURL, protocols: [String]? = nil) {
public init(url: URL, protocols: [String]? = nil) {
self.url = url
self.origin = url.absoluteString
writeQueue.maxConcurrentOperationCount = 1
@ -173,18 +173,18 @@ public class WebSocket : NSObject, NSStreamDelegate {
- Parameter forceTimeout: Maximum time to wait for the server to close the socket.
*/
public func disconnect(forceTimeout: NSTimeInterval? = nil) {
public func disconnect(_ forceTimeout: TimeInterval? = nil) {
switch forceTimeout {
case .some(let seconds) where seconds > 0:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC))), queue!) { [weak self] in
self?.disconnectStream(error: nil)
queue.after(when: DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { [weak self] in
self?.disconnectStream(nil)
}
fallthrough
case .none:
writeError(code: CloseCode.Normal.rawValue)
writeError(CloseCode.normal.rawValue)
default:
self.disconnectStream(error: nil)
self.disconnectStream(nil)
break
}
}
@ -197,9 +197,9 @@ public class WebSocket : NSObject, NSStreamDelegate {
- parameter str: The string to write.
- parameter completion: The (optional) completion handler.
*/
public func writeString(str: String, completion: (() -> ())? = nil) {
public func writeString(_ str: String, completion: (() -> ())? = nil) {
guard isConnected else { return }
dequeueWrite(data: str.data(using: NSUTF8StringEncoding)!, code: .TextFrame, writeCompletion: completion)
dequeueWrite(str.data(using: String.Encoding.utf8)!, code: .textFrame, writeCompletion: completion)
}
/**
@ -210,16 +210,16 @@ public class WebSocket : NSObject, NSStreamDelegate {
- parameter data: The data to write.
- parameter completion: The (optional) completion handler.
*/
public func writeData(data: NSData, completion: (() -> ())? = nil) {
public func writeData(_ data: Data, completion: (() -> ())? = nil) {
guard isConnected else { return }
dequeueWrite(data: data, code: .BinaryFrame, writeCompletion: completion)
dequeueWrite(data, code: .binaryFrame, writeCompletion: completion)
}
//write a ping to the websocket. This sends it as a control frame.
//yodel a sound to the planet. This sends it as an astroid. http://youtu.be/Eu5ZJELRiJ8?t=42s
public func writePing(data: NSData, completion: (() -> ())? = nil) {
public func writePing(_ data: Data, completion: (() -> ())? = nil) {
guard isConnected else { return }
dequeueWrite(data: data, code: .Ping, writeCompletion: completion)
dequeueWrite(data, code: .ping, writeCompletion: completion)
}
//private method that starts the connection
@ -230,34 +230,34 @@ public class WebSocket : NSObject, NSStreamDelegate {
var port = url.port
if port == nil {
if ["wss", "https"].contains(url.scheme) {
if ["wss", "https"].contains(url.scheme!) {
port = 443
} else {
port = 80
}
}
addHeader(urlRequest: urlRequest, key: headerWSUpgradeName as NSString, val: headerWSUpgradeValue as NSString)
addHeader(urlRequest: urlRequest, key: headerWSConnectionName as NSString, val: headerWSConnectionValue as NSString)
addHeader(urlRequest, key: headerWSUpgradeName as NSString, val: headerWSUpgradeValue as NSString)
addHeader(urlRequest, key: headerWSConnectionName as NSString, val: headerWSConnectionValue as NSString)
if let protocols = optionalProtocols {
addHeader(urlRequest: urlRequest, key: headerWSProtocolName as NSString, val: protocols.joined(separator: ",") as NSString)
addHeader(urlRequest, key: headerWSProtocolName as NSString, val: protocols.joined(separator: ",") as NSString)
}
addHeader(urlRequest: urlRequest, key: headerWSVersionName as NSString, val: headerWSVersionValue as NSString)
addHeader(urlRequest: urlRequest, key: headerWSKeyName as NSString, val: generateWebSocketKey() as NSString)
addHeader(urlRequest, key: headerWSVersionName as NSString, val: headerWSVersionValue as NSString)
addHeader(urlRequest, key: headerWSKeyName as NSString, val: generateWebSocketKey() as NSString)
if let origin = origin {
addHeader(urlRequest: urlRequest, key: headerOriginName as NSString, val: origin as NSString)
addHeader(urlRequest, key: headerOriginName as NSString, val: origin as NSString)
}
addHeader(urlRequest: urlRequest, key: headerWSHostName as NSString, val: "\(url.host!):\(port!)" as NSString)
addHeader(urlRequest, key: headerWSHostName as NSString, val: "\(url.host!):\(port!)" as NSString)
for (key,value) in headers {
addHeader(urlRequest: urlRequest, key: key as NSString, val: value as NSString)
addHeader(urlRequest, key: key as NSString, val: value as NSString)
}
if let cfHTTPMessage = CFHTTPMessageCopySerializedMessage(urlRequest) {
let serializedRequest = cfHTTPMessage.takeRetainedValue()
initStreamsWithData(data: serializedRequest, Int(port!))
initStreamsWithData(serializedRequest as Data, Int(port!))
}
}
//Add a header to the CFHTTPMessage by using the NSString bridges to CFString
private func addHeader(urlRequest: CFHTTPMessage, key: NSString, val: NSString) {
private func addHeader(_ urlRequest: CFHTTPMessage, key: NSString, val: NSString) {
CFHTTPMessageSetHeaderFieldValue(urlRequest, key, val)
}
@ -269,13 +269,13 @@ public class WebSocket : NSObject, NSStreamDelegate {
let uni = UnicodeScalar(UInt32(97 + arc4random_uniform(25)))
key += "\(Character(uni))"
}
let data = key.data(using: NSUTF8StringEncoding)
let baseKey = data?.base64EncodedString(NSDataBase64EncodingOptions(rawValue: 0))
let data = key.data(using: String.Encoding.utf8)
let baseKey = data?.base64EncodedString(NSData.Base64EncodingOptions(rawValue: 0))
return baseKey!
}
//Start the stream connection and write the data to the output stream
private func initStreamsWithData(data: NSData, _ port: Int) {
private func initStreamsWithData(_ data: Data, _ port: Int) {
//higher level API we will cut over to at some point
//NSStream.getStreamsToHostWithName(url.host, port: url.port.integerValue, inputStream: &inputStream, outputStream: &outputStream)
@ -288,15 +288,15 @@ public class WebSocket : NSObject, NSStreamDelegate {
guard let inStream = inputStream, let outStream = outputStream else { return }
inStream.delegate = self
outStream.delegate = self
if ["wss", "https"].contains(url.scheme) {
inStream.setProperty(NSStreamSocketSecurityLevelNegotiatedSSL as NSString, forKey: NSStreamSocketSecurityLevelKey)
outStream.setProperty(NSStreamSocketSecurityLevelNegotiatedSSL as NSString, forKey: NSStreamSocketSecurityLevelKey)
if ["wss", "https"].contains(url.scheme!) {
inStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as NSString, forKey: Stream.PropertyKey.socketSecurityLevelKey.rawValue)
outStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as NSString, forKey: Stream.PropertyKey.socketSecurityLevelKey.rawValue)
} else {
certValidated = true //not a https session, so no need to check SSL pinning
}
if voipEnabled {
inStream.setProperty(NSStreamNetworkServiceTypeVoIP as NSString, forKey: NSStreamNetworkServiceType)
outStream.setProperty(NSStreamNetworkServiceTypeVoIP as NSString, forKey: NSStreamNetworkServiceType)
inStream.setProperty(StreamNetworkServiceTypeValue.voip as NSString, forKey: Stream.PropertyKey.networkServiceType.rawValue)
outStream.setProperty(StreamNetworkServiceTypeValue.voip as NSString, forKey: Stream.PropertyKey.networkServiceType.rawValue)
}
if selfSignedSSL {
let settings: [NSObject: NSObject] = [kCFStreamSSLValidatesCertificateChain: NSNumber(value: false), kCFStreamSSLPeerName: kCFNull]
@ -304,18 +304,18 @@ public class WebSocket : NSObject, NSStreamDelegate {
outStream.setProperty(settings as AnyObject?, forKey: kCFStreamPropertySSLSettings as String)
}
if let cipherSuites = self.enabledSSLCipherSuites {
if let sslContextIn = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySSLContext) as! SSLContext?,
sslContextOut = CFWriteStreamCopyProperty(outputStream, kCFStreamPropertySSLContext) as! SSLContext? {
if let sslContextIn = CFReadStreamCopyProperty(inputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext?,
sslContextOut = CFWriteStreamCopyProperty(outputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext? {
let resIn = SSLSetEnabledCiphers(sslContextIn, cipherSuites, cipherSuites.count)
let resOut = SSLSetEnabledCiphers(sslContextOut, cipherSuites, cipherSuites.count)
if resIn != errSecSuccess {
let error = self.errorWithDetail(detail: "Error setting ingoing cypher suites", code: UInt16(resIn))
disconnectStream(error: error)
let error = self.errorWithDetail("Error setting ingoing cypher suites", code: UInt16(resIn))
disconnectStream(error)
return
}
if resOut != errSecSuccess {
let error = self.errorWithDetail(detail: "Error setting outgoing cypher suites", code: UInt16(resOut))
disconnectStream(error: error)
let error = self.errorWithDetail("Error setting outgoing cypher suites", code: UInt16(resOut))
disconnectStream(error)
return
}
}
@ -329,7 +329,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
self.readyToWrite = true
self.mutex.unlock()
let bytes = UnsafePointer<UInt8>(data.bytes)
let bytes = UnsafePointer<UInt8>((data as NSData).bytes)
var out = timeout * 1000000 //wait 5 seconds before giving up
writeQueue.addOperation { [weak self] in
while !outStream.hasSpaceAvailable {
@ -337,27 +337,27 @@ public class WebSocket : NSObject, NSStreamDelegate {
out -= 100
if out < 0 {
self?.cleanupStream()
self?.doDisconnect(error: self?.errorWithDetail(detail: "write wait timed out", code: 2))
self?.doDisconnect(self?.errorWithDetail("write wait timed out", code: 2))
return
} else if outStream.streamError != nil {
return //disconnectStream will be called.
}
}
outStream.write(bytes, maxLength: data.length)
outStream.write(bytes, maxLength: data.count)
}
}
//delegate for the stream methods. Processes incoming bytes
public func stream(aStream: NSStream, handle eventCode: NSStreamEvent) {
public func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
if let sec = security where !certValidated && [.hasBytesAvailable, .hasSpaceAvailable].contains(eventCode) {
let possibleTrust: AnyObject? = aStream.property(forKey: kCFStreamPropertySSLPeerTrust as String)
if let trust: AnyObject = possibleTrust {
let domain: AnyObject? = aStream.property(forKey: kCFStreamSSLPeerName as String)
if sec.isValid(trust: trust as! SecTrust, domain: domain as! String?) {
if sec.isValid(trust as! SecTrust, domain: domain as! String?) {
certValidated = true
} else {
let error = errorWithDetail(detail: "Invalid SSL certificate", code: 1)
disconnectStream(error: error)
let error = errorWithDetail("Invalid SSL certificate", code: 1)
disconnectStream(error)
return
}
}
@ -367,20 +367,20 @@ public class WebSocket : NSObject, NSStreamDelegate {
processInputStream()
}
} else if eventCode == .errorOccurred {
disconnectStream(error: aStream.streamError)
disconnectStream(aStream.streamError)
} else if eventCode == .endEncountered {
disconnectStream(error: nil)
disconnectStream(nil)
}
}
//disconnect the stream object
private func disconnectStream(error: NSError?) {
private func disconnectStream(_ error: NSError?) {
if error == nil {
writeQueue.waitUntilAllOperationsAreFinished()
} else {
writeQueue.cancelAllOperations()
}
cleanupStream()
doDisconnect(error: error)
doDisconnect(error)
}
private func cleanupStream() {
@ -409,7 +409,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
if inputQueue.count == 0 {
process = true
}
inputQueue.append(NSData(bytes: buffer, length: length))
inputQueue.append(Data(bytes: UnsafePointer<UInt8>(buffer), count: length))
if process {
dequeueInput()
}
@ -420,44 +420,44 @@ public class WebSocket : NSObject, NSStreamDelegate {
let data = inputQueue[0]
var work = data
if let fragBuffer = fragBuffer {
let combine = NSMutableData(data: fragBuffer)
var combine = NSData(data: fragBuffer) as Data
combine.append(data)
work = combine
self.fragBuffer = nil
}
let buffer = UnsafePointer<UInt8>(work.bytes)
let length = work.length
let buffer = UnsafePointer<UInt8>((work as NSData).bytes)
let length = work.count
if !connected {
processTCPHandshake(buffer: buffer, bufferLen: length)
processTCPHandshake(buffer, bufferLen: length)
} else {
processRawMessagesInBuffer(pointer: buffer, bufferLen: length)
processRawMessagesInBuffer(buffer, bufferLen: length)
}
inputQueue = inputQueue.filter{$0 != data}
}
}
//handle checking the inital connection status
private func processTCPHandshake(buffer: UnsafePointer<UInt8>, bufferLen: Int) {
let code = processHTTP(buffer: buffer, bufferLen: bufferLen)
private func processTCPHandshake(_ buffer: UnsafePointer<UInt8>, bufferLen: Int) {
let code = processHTTP(buffer, bufferLen: bufferLen)
switch code {
case 0:
connected = true
guard canDispatch else {return}
dispatch_async(queue!) { [weak self] in
queue.async { [weak self] in
guard let s = self else { return }
s.onConnect?()
s.delegate?.websocketDidConnect(socket: s)
s.notificationCenter.post(name: WebsocketDidConnectNotification, object: self)
s.delegate?.websocketDidConnect(s)
s.notificationCenter.post(name: NSNotification.Name(WebsocketDidConnectNotification), object: self)
}
case -1:
fragBuffer = NSData(bytes: buffer, length: bufferLen)
fragBuffer = Data(bytes: UnsafePointer<UInt8>(buffer), count: bufferLen)
break //do nothing, we are going to collect more data
default:
doDisconnect(error: errorWithDetail(detail: "Invalid HTTP upgrade", code: UInt16(code)))
doDisconnect(errorWithDetail("Invalid HTTP upgrade", code: UInt16(code)))
}
}
///Finds the HTTP Packet in the TCP stream, by looking for the CRLF.
private func processHTTP(buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
private func processHTTP(_ buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
let CRLFBytes = [UInt8(ascii: "\r"), UInt8(ascii: "\n"), UInt8(ascii: "\r"), UInt8(ascii: "\n")]
var k = 0
var totalSize = 0
@ -473,14 +473,14 @@ public class WebSocket : NSObject, NSStreamDelegate {
}
}
if totalSize > 0 {
let code = validateResponse(buffer: buffer, bufferLen: totalSize)
let code = validateResponse(buffer, bufferLen: totalSize)
if code != 0 {
return code
}
totalSize += 1 //skip the last \n
let restSize = bufferLen - totalSize
if restSize > 0 {
processRawMessagesInBuffer(pointer: buffer + totalSize, bufferLen: restSize)
processRawMessagesInBuffer(buffer + totalSize, bufferLen: restSize)
}
return 0 //success
}
@ -488,7 +488,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
}
///validates the HTTP is a 101 as per the RFC spec
private func validateResponse(buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
private func validateResponse(_ buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
let response = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, false).takeRetainedValue()
CFHTTPMessageAppendBytes(response, buffer, bufferLen)
let code = CFHTTPMessageGetResponseStatusCode(response)
@ -507,12 +507,12 @@ public class WebSocket : NSObject, NSStreamDelegate {
}
///read a 16 bit big endian value from a buffer
private static func readUint16(buffer: UnsafePointer<UInt8>, offset: Int) -> UInt16 {
private static func readUint16(_ buffer: UnsafePointer<UInt8>, offset: Int) -> UInt16 {
return (UInt16(buffer[offset + 0]) << 8) | UInt16(buffer[offset + 1])
}
///read a 64 bit big endian value from a buffer
private static func readUint64(buffer: UnsafePointer<UInt8>, offset: Int) -> UInt64 {
private static func readUint64(_ buffer: UnsafePointer<UInt8>, offset: Int) -> UInt64 {
var value = UInt64(0)
for i in 0...7 {
value = (value << 8) | UInt64(buffer[offset + i])
@ -521,13 +521,13 @@ public class WebSocket : NSObject, NSStreamDelegate {
}
///write a 16 bit big endian value to a buffer
private static func writeUint16(buffer: UnsafeMutablePointer<UInt8>, offset: Int, value: UInt16) {
private static func writeUint16(_ buffer: UnsafeMutablePointer<UInt8>, offset: Int, value: UInt16) {
buffer[offset + 0] = UInt8(value >> 8)
buffer[offset + 1] = UInt8(value & 0xff)
}
///write a 64 bit big endian value to a buffer
private static func writeUint64(buffer: UnsafeMutablePointer<UInt8>, offset: Int, value: UInt64) {
private static func writeUint64(_ buffer: UnsafeMutablePointer<UInt8>, offset: Int, value: UInt64) {
for i in 0...7 {
buffer[offset + i] = UInt8((value >> (8*UInt64(7 - i))) & 0xff)
}
@ -540,7 +540,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
guard let baseAddress = buffer.baseAddress else { fatalError("") }
let bufferLen = buffer.count
if response != nil && bufferLen < 2 {
fragBuffer = NSData(buffer: buffer)
fragBuffer = Data(buffer: buffer)
return emptyBuffer
}
if let response = response where response.bytesLeft > 0 {
@ -551,43 +551,43 @@ public class WebSocket : NSObject, NSStreamDelegate {
extra = 0
}
response.bytesLeft -= len
response.buffer?.append(NSData(bytes: baseAddress, length: len))
processResponse(response: response)
return buffer.fromOffset(offset: bufferLen - extra)
response.buffer?.append(Data(bytes: baseAddress, count: len))
processResponse(response)
return buffer.fromOffset(bufferLen - extra)
} else {
let isFin = (FinMask & baseAddress[0])
let receivedOpcode = OpCode(rawValue: (OpCodeMask & baseAddress[0]))
let isMasked = (MaskMask & baseAddress[1])
let payloadLen = (PayloadLenMask & baseAddress[1])
var offset = 2
if (isMasked > 0 || (RSVMask & baseAddress[0]) > 0) && receivedOpcode != .Pong {
let errCode = CloseCode.ProtocolError.rawValue
doDisconnect(error: errorWithDetail(detail: "masked and rsv data is not currently supported", code: errCode))
writeError(code: errCode)
if (isMasked > 0 || (RSVMask & baseAddress[0]) > 0) && receivedOpcode != .pong {
let errCode = CloseCode.protocolError.rawValue
doDisconnect(errorWithDetail("masked and rsv data is not currently supported", code: errCode))
writeError(errCode)
return emptyBuffer
}
let isControlFrame = (receivedOpcode == .ConnectionClose || receivedOpcode == .Ping)
if !isControlFrame && (receivedOpcode != .BinaryFrame && receivedOpcode != .ContinueFrame &&
receivedOpcode != .TextFrame && receivedOpcode != .Pong) {
let errCode = CloseCode.ProtocolError.rawValue
doDisconnect(error: errorWithDetail(detail: "unknown opcode: \(receivedOpcode)", code: errCode))
writeError(code: errCode)
let isControlFrame = (receivedOpcode == .connectionClose || receivedOpcode == .ping)
if !isControlFrame && (receivedOpcode != .binaryFrame && receivedOpcode != .continueFrame &&
receivedOpcode != .textFrame && receivedOpcode != .pong) {
let errCode = CloseCode.protocolError.rawValue
doDisconnect(errorWithDetail("unknown opcode: \(receivedOpcode)", code: errCode))
writeError(errCode)
return emptyBuffer
}
if isControlFrame && isFin == 0 {
let errCode = CloseCode.ProtocolError.rawValue
doDisconnect(error: errorWithDetail(detail: "control frames can't be fragmented", code: errCode))
writeError(code: errCode)
let errCode = CloseCode.protocolError.rawValue
doDisconnect(errorWithDetail("control frames can't be fragmented", code: errCode))
writeError(errCode)
return emptyBuffer
}
if receivedOpcode == .ConnectionClose {
var code = CloseCode.Normal.rawValue
if receivedOpcode == .connectionClose {
var code = CloseCode.normal.rawValue
if payloadLen == 1 {
code = CloseCode.ProtocolError.rawValue
code = CloseCode.protocolError.rawValue
} else if payloadLen > 1 {
code = WebSocket.readUint16(buffer: baseAddress, offset: offset)
code = WebSocket.readUint16(baseAddress, offset: offset)
if code < 1000 || (code > 1003 && code < 1007) || (code > 1011 && code < 3000) {
code = CloseCode.ProtocolError.rawValue
code = CloseCode.protocolError.rawValue
}
offset += 2
}
@ -595,70 +595,70 @@ public class WebSocket : NSObject, NSStreamDelegate {
let len = Int(payloadLen-2)
if len > 0 {
let bytes = baseAddress + offset
let str: NSString? = NSString(data: NSData(bytes: bytes, length: len), encoding: NSUTF8StringEncoding)
let str: NSString? = NSString(data: Data(bytes: bytes, count: len), encoding: String.Encoding.utf8.rawValue)
if str == nil {
code = CloseCode.ProtocolError.rawValue
code = CloseCode.protocolError.rawValue
}
}
}
doDisconnect(error: errorWithDetail(detail: "connection closed by server", code: code))
writeError(code: code)
doDisconnect(errorWithDetail("connection closed by server", code: code))
writeError(code)
return emptyBuffer
}
if isControlFrame && payloadLen > 125 {
writeError(code: CloseCode.ProtocolError.rawValue)
writeError(CloseCode.protocolError.rawValue)
return emptyBuffer
}
var dataLength = UInt64(payloadLen)
if dataLength == 127 {
dataLength = WebSocket.readUint64(buffer: baseAddress, offset: offset)
dataLength = WebSocket.readUint64(baseAddress, offset: offset)
offset += sizeof(UInt64)
} else if dataLength == 126 {
dataLength = UInt64(WebSocket.readUint16(buffer: baseAddress, offset: offset))
dataLength = UInt64(WebSocket.readUint16(baseAddress, offset: offset))
offset += sizeof(UInt16)
}
if bufferLen < offset || UInt64(bufferLen - offset) < dataLength {
fragBuffer = NSData(bytes: baseAddress, length: bufferLen)
fragBuffer = Data(bytes: baseAddress, count: bufferLen)
return emptyBuffer
}
var len = dataLength
if dataLength > UInt64(bufferLen) {
len = UInt64(bufferLen-offset)
}
let data: NSData
let data: Data
if len < 0 {
len = 0
data = NSData()
data = Data()
} else {
data = NSData(bytes: baseAddress+offset, length: Int(len))
data = Data(bytes: baseAddress+offset, count: Int(len))
}
if receivedOpcode == .Pong {
if receivedOpcode == .pong {
if canDispatch {
dispatch_async(queue!) { [weak self] in
queue.async { [weak self] in
guard let s = self else { return }
s.onPong?()
s.pongDelegate?.websocketDidReceivePong(socket: s)
s.pongDelegate?.websocketDidReceivePong(s)
}
}
return buffer.fromOffset(offset: offset + Int(len))
return buffer.fromOffset(offset + Int(len))
}
var response = readStack.last
if isControlFrame {
response = nil //don't append pings
}
if isFin == 0 && receivedOpcode == .ContinueFrame && response == nil {
let errCode = CloseCode.ProtocolError.rawValue
doDisconnect(error: errorWithDetail(detail: "continue frame before a binary or text frame", code: errCode))
writeError(code: errCode)
if isFin == 0 && receivedOpcode == .continueFrame && response == nil {
let errCode = CloseCode.protocolError.rawValue
doDisconnect(errorWithDetail("continue frame before a binary or text frame", code: errCode))
writeError(errCode)
return emptyBuffer
}
var isNew = false
if response == nil {
if receivedOpcode == .ContinueFrame {
let errCode = CloseCode.ProtocolError.rawValue
doDisconnect(error: errorWithDetail(detail: "first frame can't be a continue frame",
if receivedOpcode == .continueFrame {
let errCode = CloseCode.protocolError.rawValue
doDisconnect(errorWithDetail("first frame can't be a continue frame",
code: errCode))
writeError(code: errCode)
writeError(errCode)
return emptyBuffer
}
isNew = true
@ -667,13 +667,13 @@ public class WebSocket : NSObject, NSStreamDelegate {
response!.bytesLeft = Int(dataLength)
response!.buffer = NSMutableData(data: data)
} else {
if receivedOpcode == .ContinueFrame {
if receivedOpcode == .continueFrame {
response!.bytesLeft = Int(dataLength)
} else {
let errCode = CloseCode.ProtocolError.rawValue
doDisconnect(error: errorWithDetail(detail: "second and beyond of fragment message must be a continue frame",
let errCode = CloseCode.protocolError.rawValue
doDisconnect(errorWithDetail("second and beyond of fragment message must be a continue frame",
code: errCode))
writeError(code: errCode)
writeError(errCode)
return emptyBuffer
}
response!.buffer!.append(data)
@ -685,51 +685,52 @@ public class WebSocket : NSObject, NSStreamDelegate {
if isNew {
readStack.append(response)
}
processResponse(response: response)
processResponse(response)
}
let step = Int(offset+numericCast(len))
return buffer.fromOffset(offset: step)
return buffer.fromOffset(step)
}
}
/// Process all messages in the buffer if possible.
private func processRawMessagesInBuffer(pointer: UnsafePointer<UInt8>, bufferLen: Int) {
private func processRawMessagesInBuffer(_ pointer: UnsafePointer<UInt8>, bufferLen: Int) {
var buffer = UnsafeBufferPointer(start: pointer, count: bufferLen)
repeat {
buffer = processOneRawMessage(inBuffer: buffer)
} while buffer.count >= 2
if buffer.count > 0 {
fragBuffer = NSData(buffer: buffer)
fragBuffer = Data(buffer: buffer)
}
}
///process the finished response of a buffer
private func processResponse(response: WSResponse) -> Bool {
@discardableResult
private func processResponse(_ response: WSResponse) -> Bool {
if response.isFin && response.bytesLeft <= 0 {
if response.code == .Ping {
if response.code == .ping {
let data = response.buffer! //local copy so it is perverse for writing
dequeueWrite(data: data, code: OpCode.Pong)
} else if response.code == .TextFrame {
let str: NSString? = NSString(data: response.buffer!, encoding: NSUTF8StringEncoding)
dequeueWrite(data as Data, code: .pong)
} else if response.code == .textFrame {
let str: NSString? = NSString(data: response.buffer! as Data, encoding: String.Encoding.utf8.rawValue)
if str == nil {
writeError(code: CloseCode.Encoding.rawValue)
writeError(CloseCode.encoding.rawValue)
return false
}
if canDispatch {
dispatch_async(queue!) { [weak self] in
queue.async { [weak self] in
guard let s = self else { return }
s.onText?(str! as String)
s.delegate?.websocketDidReceiveMessage(socket: s, text: str! as String)
s.delegate?.websocketDidReceiveMessage(s, text: str! as String)
}
}
} else if response.code == .BinaryFrame {
} else if response.code == .binaryFrame {
if canDispatch {
let data = response.buffer! //local copy so it is perverse for writing
dispatch_async(queue!) { [weak self] in
queue.async { [weak self] in
guard let s = self else { return }
s.onData?(data)
s.delegate?.websocketDidReceiveData(socket: s, data: data)
s.onData?(data as Data)
s.delegate?.websocketDidReceiveData(s, data: data as Data)
}
}
}
@ -740,7 +741,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
}
///Create an error
private func errorWithDetail(detail: String, code: UInt16) -> NSError {
private func errorWithDetail(_ detail: String, code: UInt16) -> NSError {
var details = [String: String]()
details[NSLocalizedDescriptionKey] = detail
@ -752,20 +753,20 @@ public class WebSocket : NSObject, NSStreamDelegate {
}
///write a an error to the socket
private func writeError(code: UInt16) {
private func writeError(_ code: UInt16) {
let buf = NSMutableData(capacity: sizeof(UInt16))
let buffer = UnsafeMutablePointer<UInt8>(buf!.bytes)
WebSocket.writeUint16(buffer: buffer, offset: 0, value: code)
dequeueWrite(data: NSData(bytes: buffer, length: sizeof(UInt16)), code: .ConnectionClose)
WebSocket.writeUint16(buffer, offset: 0, value: code)
dequeueWrite(Data(bytes: buffer, count: sizeof(UInt16)), code: .connectionClose)
}
///used to write things to the stream
private func dequeueWrite(data: NSData, code: OpCode, writeCompletion: (() -> ())? = nil) {
private func dequeueWrite(_ data: Data, code: OpCode, writeCompletion: (() -> ())? = nil) {
writeQueue.addOperation { [weak self] in
//stream isn't ready, let's wait
guard let s = self else { return }
var offset = 2
let bytes = UnsafeMutablePointer<UInt8>(data.bytes)
let dataLength = data.length
let bytes = UnsafeMutablePointer<UInt8>((data as NSData).bytes)
let dataLength = data.count
let frame = NSMutableData(capacity: dataLength + s.MaxFrameSize)
let buffer = UnsafeMutablePointer<UInt8>(frame!.mutableBytes)
buffer[0] = s.FinMask | code.rawValue
@ -773,11 +774,11 @@ public class WebSocket : NSObject, NSStreamDelegate {
buffer[1] = CUnsignedChar(dataLength)
} else if dataLength <= Int(UInt16.max) {
buffer[1] = 126
WebSocket.writeUint16(buffer: buffer, offset: offset, value: UInt16(dataLength))
WebSocket.writeUint16(buffer, offset: offset, value: UInt16(dataLength))
offset += sizeof(UInt16)
} else {
buffer[1] = 127
WebSocket.writeUint64(buffer: buffer, offset: offset, value: UInt64(dataLength))
WebSocket.writeUint64(buffer, offset: offset, value: UInt64(dataLength))
offset += sizeof(UInt64)
}
buffer[1] |= s.MaskMask
@ -799,17 +800,17 @@ public class WebSocket : NSObject, NSStreamDelegate {
if let streamError = outStream.streamError {
error = streamError
} else {
let errCode = InternalErrorCode.OutputStreamWriteError.rawValue
error = s.errorWithDetail(detail: "output stream error during write", code: errCode)
let errCode = InternalErrorCode.outputStreamWriteError.rawValue
error = s.errorWithDetail("output stream error during write", code: errCode)
}
s.doDisconnect(error: error)
s.doDisconnect(error)
break
} else {
total += len
}
if total >= offset {
if let queue = self?.queue, callback = writeCompletion {
dispatch_async(queue) {
queue.asynchronously() {
callback()
}
}
@ -822,17 +823,17 @@ public class WebSocket : NSObject, NSStreamDelegate {
}
///used to preform the disconnect delegate
private func doDisconnect(error: NSError?) {
private func doDisconnect(_ error: NSError?) {
guard !didDisconnect else { return }
didDisconnect = true
connected = false
guard canDispatch else {return}
dispatch_async(queue!) { [weak self] in
queue.async { [weak self] in
guard let s = self else { return }
s.onDisconnect?(error)
s.delegate?.websocketDidDisconnect(socket: s, error: error)
s.delegate?.websocketDidDisconnect(s, error: error)
let userInfo = error.map({ [WebsocketDisconnectionErrorKeyName: $0] })
s.notificationCenter.post(name: WebsocketDidDisconnectNotification, object: self, userInfo: userInfo)
s.notificationCenter.post(name: NSNotification.Name(rawValue: WebsocketDidDisconnectNotification), object: self, userInfo: userInfo)
}
}
@ -855,7 +856,7 @@ private extension NSData {
private extension UnsafeBufferPointer {
func fromOffset(offset: Int) -> UnsafeBufferPointer<Element> {
func fromOffset(_ offset: Int) -> UnsafeBufferPointer<Element> {
return UnsafeBufferPointer<Element>(start: baseAddress!.advanced(by: offset), count: count - offset)
}