work on swift3 syntax

This commit is contained in:
Erik 2016-03-25 12:59:50 -04:00
parent 2f1f77141e
commit 4d4362b250
12 changed files with 196 additions and 183 deletions

View File

@ -1,4 +1,7 @@
language: objective-c language: objective-c
branches:
except:
- swift3
xcode_project: Socket.IO-Client-Swift.xcodeproj # path to your xcodeproj folder xcode_project: Socket.IO-Client-Swift.xcodeproj # path to your xcodeproj folder
xcode_scheme: SocketIO-iOS xcode_scheme: SocketIO-iOS
osx_image: xcode7.3 osx_image: xcode7.3

View File

@ -86,27 +86,27 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
for option in options { for option in options {
switch option { switch option {
case let .ConnectParams(params): case let .connectParams(params):
connectParams = params connectParams = params
case let .Cookies(cookies): case let .cookies(cookies):
self.cookies = cookies self.cookies = cookies
case let .DoubleEncodeUTF8(encode): case let .doubleEncodeUTF8(encode):
doubleEncodeUTF8 = encode doubleEncodeUTF8 = encode
case let .ExtraHeaders(headers): case let .extraHeaders(headers):
extraHeaders = headers extraHeaders = headers
case let .SessionDelegate(delegate): case let .sessionDelegate(delegate):
sessionDelegate = delegate sessionDelegate = delegate
case let .ForcePolling(force): case let .forcePolling(force):
forcePolling = force forcePolling = force
case let .ForceWebsockets(force): case let .forceWebsockets(force):
forceWebsockets = force forceWebsockets = force
case let .Path(path): case let .path(path):
socketPath = path socketPath = path
case let .VoipEnabled(enable): case let .voipEnabled(enable):
voipEnabled = enable voipEnabled = enable
case let .Secure(secure): case let .secure(secure):
self.secure = secure self.secure = secure
case let .SelfSigned(selfSigned): case let .selfSigned(selfSigned):
self.selfSigned = selfSigned self.selfSigned = selfSigned
default: default:
continue continue
@ -129,12 +129,12 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
} }
private func checkAndHandleEngineError(msg: String) { private func checkAndHandleEngineError(msg: String) {
guard let stringData = msg.dataUsingEncoding(NSUTF8StringEncoding, guard let stringData = msg.data(usingEncoding: NSUTF8StringEncoding,
allowLossyConversion: false) else { return } allowLossyConversion: false) else { return }
do { do {
if let dict = try NSJSONSerialization.JSONObjectWithData(stringData, if let dict = try NSJSONSerialization.jsonObject(with: stringData,
options: NSJSONReadingOptions.MutableContainers) as? NSDictionary { options: NSJSONReadingOptions.mutableContainers) as? NSDictionary {
guard let code = dict["code"] as? Int else { return } guard let code = dict["code"] as? Int else { return }
guard let error = dict["message"] as? String else { return } guard let error = dict["message"] as? String else { return }
@ -159,10 +159,10 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
private func checkIfMessageIsBase64Binary(message: String) -> Bool { private func checkIfMessageIsBase64Binary(message: String) -> Bool {
if message.hasPrefix("b4") { if message.hasPrefix("b4") {
// binary in base64 string // binary in base64 string
let noPrefix = message[message.startIndex.advancedBy(2)..<message.endIndex] let noPrefix = message[message.startIndex.advanced(by: 2)..<message.endIndex]
if let data = NSData(base64EncodedString: noPrefix, if let data = NSData(base64EncodedString: noPrefix,
options: .IgnoreUnknownCharacters) { options: .ignoreUnknownCharacters) {
client?.parseEngineBinaryData(data) client?.parseEngineBinaryData(data)
} }
@ -191,10 +191,10 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
return return
} }
let reqPolling = NSMutableURLRequest(URL: urlPolling) let reqPolling = NSMutableURLRequest(url: urlPolling)
if cookies != nil { if cookies != nil {
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) let headers = NSHTTPCookie.requestHeaderFields(with: cookies!)
reqPolling.allHTTPHeaderFields = headers reqPolling.allHTTPHeaderFields = headers
} }
@ -238,14 +238,14 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
urlWebSocket.query = urlWebSocket.query! + queryString urlWebSocket.query = urlWebSocket.query! + queryString
urlPolling.query = urlPolling.query! + queryString urlPolling.query = urlPolling.query! + queryString
return (urlPolling.URL!, urlWebSocket.URL!) return (urlPolling.url!, urlWebSocket.url!)
} }
private func createWebsocketAndConnect() { private func createWebsocketAndConnect() {
ws = WebSocket(url: urlWebSocketWithSid) ws = WebSocket(url: urlWebSocketWithSid)
if cookies != nil { if cookies != nil {
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) let headers = NSHTTPCookie.requestHeaderFields(with: cookies!)
for (key, value) in headers { for (key, value) in headers {
ws?.headers[key] = value ws?.headers[key] = value
} }
@ -325,7 +325,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
self.write(waiter.msg, withType: waiter.type, withData: waiter.data) self.write(waiter.msg, withType: waiter.type, withData: waiter.data)
} }
self.probeWait.removeAll(keepCapacity: false) self.probeWait.removeAll(keepingCapacity: false)
if self.postWait.count != 0 { if self.postWait.count != 0 {
self.flushWaitingForPostToWebSocket() self.flushWaitingForPostToWebSocket()
@ -342,7 +342,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
ws.writeString(fixDoubleUTF8(msg)) ws.writeString(fixDoubleUTF8(msg))
} }
postWait.removeAll(keepCapacity: true) postWait.removeAll(keepingCapacity: true)
} }
private func handleClose(reason: String) { private func handleClose(reason: String) {
@ -358,10 +358,10 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
} }
private func handleOpen(openData: String) { private func handleOpen(openData: String) {
let mesData = openData.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! let mesData = openData.data(usingEncoding: NSUTF8StringEncoding, allowLossyConversion: false)!
do { do {
let json = try NSJSONSerialization.JSONObjectWithData(mesData, let json = try NSJSONSerialization.jsonObject(with: mesData,
options: NSJSONReadingOptions.AllowFragments) as? NSDictionary options: NSJSONReadingOptions.allowFragments) as? NSDictionary
if let sid = json?["sid"] as? String { if let sid = json?["sid"] as? String {
let upgradeWs: Bool let upgradeWs: Bool
@ -408,7 +408,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
public func parseEngineData(data: NSData) { public func parseEngineData(data: NSData) {
DefaultSocketLogger.Logger.log("Got binary data: %@", type: "SocketEngine", args: data) DefaultSocketLogger.Logger.log("Got binary data: %@", type: "SocketEngine", args: data)
client?.parseEngineBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1))) client?.parseEngineBinaryData(data.subdata(with: NSMakeRange(1, data.length - 1)))
} }
public func parseEngineMessage(message: String, fromPolling: Bool) { public func parseEngineMessage(message: String, fromPolling: Bool) {

View File

@ -47,7 +47,7 @@ public protocol SocketEnginePollable : SocketEngineSpec {
extension SocketEnginePollable { extension SocketEnginePollable {
private func addHeaders(req: NSMutableURLRequest) { private func addHeaders(req: NSMutableURLRequest) {
if cookies != nil { if cookies != nil {
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) let headers = NSHTTPCookie.requestHeaderFields(with: cookies!)
req.allHTTPHeaderFields = headers req.allHTTPHeaderFields = headers
} }
@ -69,19 +69,19 @@ extension SocketEnginePollable {
DefaultSocketLogger.Logger.log("Created POST string: %@", type: "SocketEnginePolling", args: postStr) DefaultSocketLogger.Logger.log("Created POST string: %@", type: "SocketEnginePolling", args: postStr)
postWait.removeAll(keepCapacity: false) postWait.removeAll(keepingCapacity: false)
let req = NSMutableURLRequest(URL: urlPollingWithSid) let req = NSMutableURLRequest(url: urlPollingWithSid)
addHeaders(req) addHeaders(req)
req.HTTPMethod = "POST" req.httpMethod = "POST"
req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type") req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
let postData = postStr.dataUsingEncoding(NSUTF8StringEncoding, let postData = postStr.data(usingEncoding: NSUTF8StringEncoding,
allowLossyConversion: false)! allowLossyConversion: false)!
req.HTTPBody = postData req.httpBody = postData
req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length") req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length")
return req return req
@ -93,7 +93,7 @@ extension SocketEnginePollable {
} }
waitingForPoll = true waitingForPoll = true
let req = NSMutableURLRequest(URL: urlPollingWithSid) let req = NSMutableURLRequest(url: urlPollingWithSid)
addHeaders(req) addHeaders(req)
doLongPoll(req) doLongPoll(req)
@ -107,7 +107,7 @@ extension SocketEnginePollable {
DefaultSocketLogger.Logger.log("Doing polling request", type: "SocketEnginePolling") DefaultSocketLogger.Logger.log("Doing polling request", type: "SocketEnginePolling")
session?.dataTaskWithRequest(req, completionHandler: callback).resume() session?.dataTask(with: req, completionHandler: callback).resume()
} }
func doLongPoll(req: NSURLRequest) { func doLongPoll(req: NSURLRequest) {

View File

@ -61,36 +61,36 @@ import Foundation
extension SocketEngineSpec { extension SocketEngineSpec {
var urlPollingWithSid: NSURL { var urlPollingWithSid: NSURL {
let com = NSURLComponents(URL: urlPolling, resolvingAgainstBaseURL: false)! let com = NSURLComponents(url: urlPolling, resolvingAgainstBaseURL: false)!
com.query = com.query! + "&sid=\(sid)" com.query = com.query! + "&sid=\(sid)"
return com.URL! return com.url!
} }
var urlWebSocketWithSid: NSURL { var urlWebSocketWithSid: NSURL {
let com = NSURLComponents(URL: urlWebSocket, resolvingAgainstBaseURL: false)! let com = NSURLComponents(url: urlWebSocket, resolvingAgainstBaseURL: false)!
com.query = com.query! + (sid == "" ? "" : "&sid=\(sid)") com.query = com.query! + (sid == "" ? "" : "&sid=\(sid)")
return com.URL! return com.url!
} }
func createBinaryDataForSend(data: NSData) -> Either<NSData, String> { func createBinaryDataForSend(data: NSData) -> Either<NSData, String> {
if websocket { if websocket {
var byteArray = [UInt8](count: 1, repeatedValue: 0x4) var byteArray = [UInt8](repeating: 0x4, count: 1)
let mutData = NSMutableData(bytes: &byteArray, length: 1) let mutData = NSMutableData(bytes: &byteArray, length: 1)
mutData.appendData(data) mutData.append(data)
return .Left(mutData) return .Left(mutData)
} else { } else {
let str = "b4" + data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) let str = "b4" + data.base64EncodedString(NSDataBase64EncodingOptions(rawValue: 0))
return .Right(str) return .Right(str)
} }
} }
func doubleEncodeUTF8(string: String) -> String { func doubleEncodeUTF8(string: String) -> String {
if let latin1 = string.dataUsingEncoding(NSUTF8StringEncoding), if let latin1 = string.data(usingEncoding: NSUTF8StringEncoding),
utf8 = NSString(data: latin1, encoding: NSISOLatin1StringEncoding) { utf8 = NSString(data: latin1, encoding: NSISOLatin1StringEncoding) {
return utf8 as String return utf8 as String
} else { } else {
@ -99,7 +99,7 @@ extension SocketEngineSpec {
} }
func fixDoubleUTF8(string: String) -> String { func fixDoubleUTF8(string: String) -> String {
if let utf8 = string.dataUsingEncoding(NSISOLatin1StringEncoding), if let utf8 = string.data(usingEncoding: NSISOLatin1StringEncoding),
latin1 = NSString(data: utf8, encoding: NSUTF8StringEncoding) { latin1 = NSString(data: utf8, encoding: NSUTF8StringEncoding) {
return latin1 as String return latin1 as String
} else { } else {

View File

@ -71,33 +71,33 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
self.socketURL = socketURL self.socketURL = socketURL
if socketURL.absoluteString.hasPrefix("https://") { if socketURL.absoluteString.hasPrefix("https://") {
self.options.insertIgnore(.Secure(true)) self.options.insertIgnore(.secure(true))
} }
for option in options { for option in options {
switch option { switch option {
case let .Reconnects(reconnects): case let .reconnects(reconnects):
self.reconnects = reconnects self.reconnects = reconnects
case let .ReconnectAttempts(attempts): case let .reconnectAttempts(attempts):
reconnectAttempts = attempts reconnectAttempts = attempts
case let .ReconnectWait(wait): case let .reconnectWait(wait):
reconnectWait = abs(wait) reconnectWait = abs(wait)
case let .Nsp(nsp): case let .nsp(nsp):
self.nsp = nsp self.nsp = nsp
case let .Log(log): case let .log(log):
DefaultSocketLogger.Logger.log = log DefaultSocketLogger.Logger.log = log
case let .Logger(logger): case let .logger(logger):
DefaultSocketLogger.Logger = logger DefaultSocketLogger.Logger = logger
case let .HandleQueue(queue): case let .handleQueue(queue):
handleQueue = queue handleQueue = queue
case let .ForceNew(force): case let .forceNew(force):
forceNew = force forceNew = force
default: default:
continue continue
} }
} }
self.options.insertIgnore(.Path("/socket.io/")) self.options.insertIgnore(.path("/socket.io/"))
super.init() super.init()
} }
@ -409,7 +409,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
/// Removes all handlers. /// Removes all handlers.
/// Can be used after disconnecting to break any potential remaining retain cycles. /// Can be used after disconnecting to break any potential remaining retain cycles.
public func removeAllHandlers() { public func removeAllHandlers() {
handlers.removeAll(keepCapacity: false) handlers.removeAll(keepingCapacity: false)
} }
private func tryReconnectWithReason(reason: String) { private func tryReconnectWithReason(reason: String) {

View File

@ -29,67 +29,67 @@ protocol ClientOption : CustomStringConvertible, Hashable {
} }
public enum SocketIOClientOption : ClientOption { public enum SocketIOClientOption : ClientOption {
case ConnectParams([String: AnyObject]) case connectParams([String: AnyObject])
case Cookies([NSHTTPCookie]) case cookies([NSHTTPCookie])
case DoubleEncodeUTF8(Bool) case doubleEncodeUTF8(Bool)
case ExtraHeaders([String: String]) case extraHeaders([String: String])
case ForceNew(Bool) case forceNew(Bool)
case ForcePolling(Bool) case forcePolling(Bool)
case ForceWebsockets(Bool) case forceWebsockets(Bool)
case HandleQueue(dispatch_queue_t) case handleQueue(dispatch_queue_t)
case Log(Bool) case log(Bool)
case Logger(SocketLogger) case logger(SocketLogger)
case Nsp(String) case nsp(String)
case Path(String) case path(String)
case Reconnects(Bool) case reconnects(Bool)
case ReconnectAttempts(Int) case reconnectAttempts(Int)
case ReconnectWait(Int) case reconnectWait(Int)
case Secure(Bool) case secure(Bool)
case SelfSigned(Bool) case selfSigned(Bool)
case SessionDelegate(NSURLSessionDelegate) case sessionDelegate(NSURLSessionDelegate)
case VoipEnabled(Bool) case voipEnabled(Bool)
public var description: String { public var description: String {
let description: String let description: String
switch self { switch self {
case .ConnectParams: case .connectParams:
description = "connectParams" description = "connectParams"
case .Cookies: case .cookies:
description = "cookies" description = "cookies"
case .DoubleEncodeUTF8: case .doubleEncodeUTF8:
description = "doubleEncodeUTF8" description = "doubleEncodeUTF8"
case .ExtraHeaders: case .extraHeaders:
description = "extraHeaders" description = "extraHeaders"
case .ForceNew: case .forceNew:
description = "forceNew" description = "forceNew"
case .ForcePolling: case .forcePolling:
description = "forcePolling" description = "forcePolling"
case .ForceWebsockets: case .forceWebsockets:
description = "forceWebsockets" description = "forceWebsockets"
case .HandleQueue: case .handleQueue:
description = "handleQueue" description = "handleQueue"
case .Log: case .log:
description = "log" description = "log"
case .Logger: case .logger:
description = "logger" description = "logger"
case .Nsp: case .nsp:
description = "nsp" description = "nsp"
case .Path: case .path:
description = "path" description = "path"
case .Reconnects: case .reconnects:
description = "reconnects" description = "reconnects"
case .ReconnectAttempts: case .reconnectAttempts:
description = "reconnectAttempts" description = "reconnectAttempts"
case .ReconnectWait: case .reconnectWait:
description = "reconnectWait" description = "reconnectWait"
case .Secure: case .secure:
description = "secure" description = "secure"
case .SelfSigned: case .selfSigned:
description = "selfSigned" description = "selfSigned"
case .SessionDelegate: case .sessionDelegate:
description = "sessionDelegate" description = "sessionDelegate"
case .VoipEnabled: case .voipEnabled:
description = "voipEnabled" description = "voipEnabled"
} }
@ -104,43 +104,43 @@ public enum SocketIOClientOption : ClientOption {
let value: AnyObject let value: AnyObject
switch self { switch self {
case let .ConnectParams(params): case let .connectParams(params):
value = params value = params
case let .Cookies(cookies): case let .cookies(cookies):
value = cookies value = cookies
case let .DoubleEncodeUTF8(encode): case let .doubleEncodeUTF8(encode):
value = encode value = encode
case let .ExtraHeaders(headers): case let .extraHeaders(headers):
value = headers value = headers
case let .ForceNew(force): case let .forceNew(force):
value = force value = force
case let .ForcePolling(force): case let .forcePolling(force):
value = force value = force
case let .ForceWebsockets(force): case let .forceWebsockets(force):
value = force value = force
case let .HandleQueue(queue): case let .handleQueue(queue):
value = queue value = queue
case let .Log(log): case let .log(log):
value = log value = log
case let .Logger(logger): case let .logger(logger):
value = logger value = logger
case let .Nsp(nsp): case let .nsp(nsp):
value = nsp value = nsp
case let .Path(path): case let .path(path):
value = path value = path
case let .Reconnects(reconnects): case let .reconnects(reconnects):
value = reconnects value = reconnects
case let .ReconnectAttempts(attempts): case let .reconnectAttempts(attempts):
value = attempts value = attempts
case let .ReconnectWait(wait): case let .reconnectWait(wait):
value = wait value = wait
case let .Secure(secure): case let .secure(secure):
value = secure value = secure
case let .SelfSigned(signed): case let .selfSigned(signed):
value = signed value = signed
case let .SessionDelegate(delegate): case let .sessionDelegate(delegate):
value = delegate value = delegate
case let .VoipEnabled(enabled): case let .voipEnabled(enabled):
value = enabled value = enabled
} }
@ -164,43 +164,43 @@ extension NSDictionary {
private static func keyValueToSocketIOClientOption(key: String, value: AnyObject) -> SocketIOClientOption? { private static func keyValueToSocketIOClientOption(key: String, value: AnyObject) -> SocketIOClientOption? {
switch (key, value) { switch (key, value) {
case let ("connectParams", params as [String: AnyObject]): case let ("connectParams", params as [String: AnyObject]):
return .ConnectParams(params) return .connectParams(params)
case let ("cookies", cookies as [NSHTTPCookie]): case let ("cookies", cookies as [NSHTTPCookie]):
return .Cookies(cookies) return .cookies(cookies)
case let ("doubleEncodeUTF8", encode as Bool): case let ("doubleEncodeUTF8", encode as Bool):
return .DoubleEncodeUTF8(encode) return .doubleEncodeUTF8(encode)
case let ("extraHeaders", headers as [String: String]): case let ("extraHeaders", headers as [String: String]):
return .ExtraHeaders(headers) return .extraHeaders(headers)
case let ("forceNew", force as Bool): case let ("forceNew", force as Bool):
return .ForceNew(force) return .forceNew(force)
case let ("forcePolling", force as Bool): case let ("forcePolling", force as Bool):
return .ForcePolling(force) return .forcePolling(force)
case let ("forceWebsockets", force as Bool): case let ("forceWebsockets", force as Bool):
return .ForceWebsockets(force) return .forceWebsockets(force)
case let ("handleQueue", queue as dispatch_queue_t): case let ("handleQueue", queue as dispatch_queue_t):
return .HandleQueue(queue) return .handleQueue(queue)
case let ("log", log as Bool): case let ("log", log as Bool):
return .Log(log) return .log(log)
case let ("logger", logger as SocketLogger): case let ("logger", logger as SocketLogger):
return .Logger(logger) return .logger(logger)
case let ("nsp", nsp as String): case let ("nsp", nsp as String):
return .Nsp(nsp) return .nsp(nsp)
case let ("path", path as String): case let ("path", path as String):
return .Path(path) return .path(path)
case let ("reconnects", reconnects as Bool): case let ("reconnects", reconnects as Bool):
return .Reconnects(reconnects) return .reconnects(reconnects)
case let ("reconnectAttempts", attempts as Int): case let ("reconnectAttempts", attempts as Int):
return .ReconnectAttempts(attempts) return .reconnectAttempts(attempts)
case let ("reconnectWait", wait as Int): case let ("reconnectWait", wait as Int):
return .ReconnectWait(wait) return .reconnectWait(wait)
case let ("secure", secure as Bool): case let ("secure", secure as Bool):
return .Secure(secure) return .secure(secure)
case let ("selfSigned", selfSigned as Bool): case let ("selfSigned", selfSigned as Bool):
return .SelfSigned(selfSigned) return .selfSigned(selfSigned)
case let ("sessionDelegate", delegate as NSURLSessionDelegate): case let ("sessionDelegate", delegate as NSURLSessionDelegate):
return .SessionDelegate(delegate) return .sessionDelegate(delegate)
case let ("voipEnabled", enable as Bool): case let ("voipEnabled", enable as Bool):
return .VoipEnabled(enable) return .voipEnabled(enable)
default: default:
return nil return nil
} }

View File

@ -47,7 +47,7 @@ public extension SocketLogger {
private func abstractLog(logType: String, message: String, type: String, args: [AnyObject]) { private func abstractLog(logType: String, message: String, type: String, args: [AnyObject]) {
guard log else { return } guard log else { return }
let newArgs = args.map({arg -> CVarArgType in String(arg)}) let newArgs = args.map({arg -> CVarArg in String(arg)})
let replaced = String(format: message, arguments: newArgs) let replaced = String(format: message, arguments: newArgs)
NSLog("%@ %@: %@", logType, type, replaced) NSLog("%@ %@: %@", logType, type, replaced)

View File

@ -94,7 +94,7 @@ struct SocketPacket {
} }
do { do {
let jsonSend = try NSJSONSerialization.dataWithJSONObject(data, let jsonSend = try NSJSONSerialization.data(withJSONObject: data,
options: NSJSONWritingOptions(rawValue: 0)) options: NSJSONWritingOptions(rawValue: 0))
guard let jsonString = String(data: jsonSend, encoding: NSUTF8StringEncoding) else { guard let jsonString = String(data: jsonSend, encoding: NSUTF8StringEncoding) else {
return "[]" return "[]"
@ -235,7 +235,7 @@ extension SocketPacket {
private extension SocketPacket { private extension SocketPacket {
// Recursive function that looks for NSData in collections // Recursive function that looks for NSData in collections
static func shred(data: AnyObject, inout binary: [NSData]) -> AnyObject { static func shred(data: AnyObject, binary: inout [NSData]) -> AnyObject {
let placeholder = ["_placeholder": true, "num": binary.count] let placeholder = ["_placeholder": true, "num": binary.count]
switch data { switch data {

View File

@ -111,7 +111,7 @@ extension SocketParsable {
} }
} }
let d = message[parser.currentIndex.advancedBy(1)..<message.endIndex] let d = message[parser.currentIndex.advanced(by: 1)..<message.endIndex]
let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] <~ "\"~~$2\"" let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] <~ "\"~~$2\""
switch parseData(noPlaceholders) { switch parseData(noPlaceholders) {
@ -131,10 +131,10 @@ extension SocketParsable {
// Parses data for events // Parses data for events
private func parseData(data: String) -> Either<String, [AnyObject]> { private func parseData(data: String) -> Either<String, [AnyObject]> {
let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) let stringData = data.data(usingEncoding: NSUTF8StringEncoding, allowLossyConversion: false)
do { do {
if let arr = try NSJSONSerialization.JSONObjectWithData(stringData!, if let arr = try NSJSONSerialization.jsonObject(with: stringData!,
options: NSJSONReadingOptions.MutableContainers) as? [AnyObject] { options: NSJSONReadingOptions.mutableContainers) as? [AnyObject] {
return .Right(arr) return .Right(arr)
} else { } else {
return .Left("Expected data array") return .Left("Expected data array")

View File

@ -39,11 +39,11 @@ struct SocketStringReader {
} }
mutating func advanceIndexBy(n: Int) { mutating func advanceIndexBy(n: Int) {
currentIndex = currentIndex.advancedBy(n) currentIndex = currentIndex.advanced(by: n)
} }
mutating func read(readLength: Int) -> String { mutating func read(readLength: Int) -> String {
let readString = message[currentIndex..<currentIndex.advancedBy(readLength)] let readString = message[currentIndex..<currentIndex.advanced(by: readLength)]
advanceIndexBy(readLength) advanceIndexBy(readLength)
return readString return readString
@ -51,18 +51,18 @@ struct SocketStringReader {
mutating func readUntilStringOccurence(string: String) -> String { mutating func readUntilStringOccurence(string: String) -> String {
let substring = message[currentIndex..<message.endIndex] let substring = message[currentIndex..<message.endIndex]
guard let foundRange = substring.rangeOfString(string) else { guard let foundRange = substring.range(of: string) else {
currentIndex = message.endIndex currentIndex = message.endIndex
return substring return substring
} }
advanceIndexBy(message.startIndex.distanceTo(foundRange.startIndex) + 1) advanceIndexBy(message.startIndex.distance(to: foundRange.startIndex) + 1)
return substring.substringToIndex(foundRange.startIndex) return substring.substring(to: foundRange.startIndex)
} }
mutating func readUntilEnd() -> String { mutating func readUntilEnd() -> String {
return read(currentIndex.distanceTo(message.endIndex)) return read(currentIndex.distance(to: message.endIndex))
} }
} }

View File

@ -18,7 +18,7 @@ infix operator <~ { associativity none precedence 130 }
private let lock = dispatch_semaphore_create(1) private let lock = dispatch_semaphore_create(1)
private var swiftRegexCache = [String: NSRegularExpression]() private var swiftRegexCache = [String: NSRegularExpression]()
internal final class SwiftRegex : NSObject, BooleanType { internal final class SwiftRegex : NSObject, Boolean {
var target: String var target: String
var regex: NSRegularExpression var regex: NSRegularExpression
@ -28,7 +28,7 @@ internal final class SwiftRegex : NSObject, BooleanType {
if dispatch_semaphore_wait(lock, dispatch_time(DISPATCH_TIME_NOW, Int64(10 * NSEC_PER_MSEC))) != 0 { if dispatch_semaphore_wait(lock, dispatch_time(DISPATCH_TIME_NOW, Int64(10 * NSEC_PER_MSEC))) != 0 {
do { do {
let regex = try NSRegularExpression(pattern: pattern, options: let regex = try NSRegularExpression(pattern: pattern, options:
NSRegularExpressionOptions.DotMatchesLineSeparators) NSRegularExpressionOptions.dotMatchesLineSeparators)
self.regex = regex self.regex = regex
} catch let error as NSError { } catch let error as NSError {
SwiftRegex.failure("Error in pattern: \(pattern) - \(error)") SwiftRegex.failure("Error in pattern: \(pattern) - \(error)")
@ -44,7 +44,7 @@ internal final class SwiftRegex : NSObject, BooleanType {
} else { } else {
do { do {
let regex = try NSRegularExpression(pattern: pattern, options: let regex = try NSRegularExpression(pattern: pattern, options:
NSRegularExpressionOptions.DotMatchesLineSeparators) NSRegularExpressionOptions.dotMatchesLineSeparators)
swiftRegexCache[pattern] = regex swiftRegexCache[pattern] = regex
self.regex = regex self.regex = regex
} catch let error as NSError { } catch let error as NSError {
@ -66,7 +66,7 @@ internal final class SwiftRegex : NSObject, BooleanType {
private func substring(range: NSRange) -> String? { private func substring(range: NSRange) -> String? {
if range.location != NSNotFound { if range.location != NSNotFound {
return (target as NSString).substringWithRange(range) return (target as NSString).substring(with: range)
} else { } else {
return nil return nil
} }
@ -77,7 +77,7 @@ internal final class SwiftRegex : NSObject, BooleanType {
} }
func range(options: NSMatchingOptions) -> NSRange { func range(options: NSMatchingOptions) -> NSRange {
return regex.rangeOfFirstMatchInString(target as String, options: [], range: targetRange) return regex.rangeOfFirstMatch(in: target as String, options: [], range: targetRange)
} }
func match(options: NSMatchingOptions) -> String? { func match(options: NSMatchingOptions) -> String? {
@ -85,8 +85,8 @@ internal final class SwiftRegex : NSObject, BooleanType {
} }
func groups() -> [String]? { func groups() -> [String]? {
return groupsForMatch(regex.firstMatchInString(target as String, options: return groupsForMatch(regex.firstMatch(in: target as String, options:
NSMatchingOptions.WithoutAnchoringBounds, range: targetRange)) NSMatchingOptions.withoutAnchoringBounds, range: targetRange))
} }
private func groupsForMatch(match: NSTextCheckingResult?) -> [String]? { private func groupsForMatch(match: NSTextCheckingResult?) -> [String]? {
@ -95,7 +95,7 @@ internal final class SwiftRegex : NSObject, BooleanType {
} }
var groups = [String]() var groups = [String]()
for groupno in 0...regex.numberOfCaptureGroups { for groupno in 0...regex.numberOfCaptureGroups {
if let group = substring(match.rangeAtIndex(groupno)) { if let group = substring(match.range(at: groupno)) {
groups += [group] groups += [group]
} else { } else {
groups += ["_"] // avoids bridging problems groups += ["_"] // avoids bridging problems
@ -114,11 +114,11 @@ internal final class SwiftRegex : NSObject, BooleanType {
return return
} }
for match in Array(matchResults().reverse()) { for match in Array(matchResults().reversed()) {
let replacement = regex.replacementStringForResult(match, let replacement = regex.replacementString(for: match,
inString: target as String, offset: 0, template: newValue!) in: target as String, offset: 0, template: newValue!)
let mut = NSMutableString(string: target) let mut = NSMutableString(string: target)
mut.replaceCharactersInRange(match.rangeAtIndex(groupno), withString: replacement) mut.replaceCharacters(in: match.range(at: groupno), with: replacement)
target = mut as String target = mut as String
} }
@ -126,8 +126,8 @@ internal final class SwiftRegex : NSObject, BooleanType {
} }
func matchResults() -> [NSTextCheckingResult] { func matchResults() -> [NSTextCheckingResult] {
let matches = regex.matchesInString(target as String, options: let matches = regex.matches(in: target as String, options:
NSMatchingOptions.WithoutAnchoringBounds, range: targetRange) NSMatchingOptions.withoutAnchoringBounds, range: targetRange)
as [NSTextCheckingResult] as [NSTextCheckingResult]
return matches return matches
@ -148,7 +148,7 @@ internal final class SwiftRegex : NSObject, BooleanType {
func dictionary(options: NSMatchingOptions!) -> Dictionary<String,String> { func dictionary(options: NSMatchingOptions!) -> Dictionary<String,String> {
var out = Dictionary<String,String>() var out = Dictionary<String,String>()
for match in matchResults() { for match in matchResults() {
out[substring(match.rangeAtIndex(1))!] = substring(match.rangeAtIndex(2))! out[substring(match.range(at: 1))!] = substring(match.range(at: 2))!
} }
return out return out
} }
@ -158,14 +158,14 @@ internal final class SwiftRegex : NSObject, BooleanType {
let out = NSMutableString() let out = NSMutableString()
var pos = 0 var pos = 0
regex.enumerateMatchesInString(target as String, options: options, range: targetRange ) {match, flags, stop in regex.enumerateMatches(in: target as String, options: options, range: targetRange ) {match, flags, stop in
let matchRange = match!.range let matchRange = match!.range
out.appendString( self.substring(NSRange(location:pos, length:matchRange.location-pos))!) out.append( self.substring(NSRange(location:pos, length:matchRange.location-pos))!)
out.appendString( substitution(match!, stop) ) out.append( substitution(match!, stop) )
pos = matchRange.location + matchRange.length pos = matchRange.location + matchRange.length
} }
out.appendString(substring(NSRange(location:pos, length:targetRange.length-pos))!) out.append(substring(NSRange(location:pos, length:targetRange.length-pos))!)
return out as String return out as String
} }
@ -189,7 +189,6 @@ extension String {
func <~ (left: SwiftRegex, right: String) -> String { func <~ (left: SwiftRegex, right: String) -> String {
return left.substituteMatches({match, stop in return left.substituteMatches({match, stop in
return left.regex.replacementStringForResult( match, return left.regex.replacementString(for: match, in: left.target as String, offset: 0, template: right )
inString: left.target as String, offset: 0, template: right )
}, options: []) }, options: [])
} }

View File

@ -109,7 +109,10 @@ public class WebSocket : NSObject, NSStreamDelegate {
public var headers = [String: String]() public var headers = [String: String]()
public var voipEnabled = false public var voipEnabled = false
public var selfSignedSSL = false public var selfSignedSSL = false
#if swift(>=3)
#else
public var security: SSLSecurity? public var security: SSLSecurity?
#endif
public var enabledSSLCipherSuites: [SSLCipherSuite]? public var enabledSSLCipherSuites: [SSLCipherSuite]?
public var origin: String? public var origin: String?
public var isConnected :Bool { public var isConnected :Bool {
@ -166,12 +169,12 @@ public class WebSocket : NSObject, NSStreamDelegate {
*/ */
public func disconnect(forceTimeout forceTimeout: NSTimeInterval? = nil) { public func disconnect(forceTimeout forceTimeout: NSTimeInterval? = nil) {
switch forceTimeout { switch forceTimeout {
case .Some(let seconds) where seconds > 0: case .some(let seconds) where seconds > 0:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC))), queue) { [weak self] in dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC))), queue) { [weak self] in
self?.disconnectStream(nil) self?.disconnectStream(nil)
} }
fallthrough fallthrough
case .None: case .none:
writeError(CloseCode.Normal.rawValue) writeError(CloseCode.Normal.rawValue)
default: default:
@ -183,7 +186,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
///write a string to the websocket. This sends it as a text frame. ///write a string to the websocket. This sends it as a text frame.
public func writeString(str: String) { public func writeString(str: String) {
guard isConnected else { return } guard isConnected else { return }
dequeueWrite(str.dataUsingEncoding(NSUTF8StringEncoding)!, code: .TextFrame) dequeueWrite(str.data(usingEncoding: NSUTF8StringEncoding)!, code: .TextFrame)
} }
///write binary data to the websocket. This sends it as a binary frame. ///write binary data to the websocket. This sends it as a binary frame.
@ -216,7 +219,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
addHeader(urlRequest, key: headerWSUpgradeName, val: headerWSUpgradeValue) addHeader(urlRequest, key: headerWSUpgradeName, val: headerWSUpgradeValue)
addHeader(urlRequest, key: headerWSConnectionName, val: headerWSConnectionValue) addHeader(urlRequest, key: headerWSConnectionName, val: headerWSConnectionValue)
if let protocols = optionalProtocols { if let protocols = optionalProtocols {
addHeader(urlRequest, key: headerWSProtocolName, val: protocols.joinWithSeparator(",")) addHeader(urlRequest, key: headerWSProtocolName, val: protocols.joined(separator: ","))
} }
addHeader(urlRequest, key: headerWSVersionName, val: headerWSVersionValue) addHeader(urlRequest, key: headerWSVersionName, val: headerWSVersionValue)
addHeader(urlRequest, key: headerWSKeyName, val: generateWebSocketKey()) addHeader(urlRequest, key: headerWSKeyName, val: generateWebSocketKey())
@ -246,8 +249,8 @@ public class WebSocket : NSObject, NSStreamDelegate {
let uni = UnicodeScalar(UInt32(97 + arc4random_uniform(25))) let uni = UnicodeScalar(UInt32(97 + arc4random_uniform(25)))
key += "\(Character(uni))" key += "\(Character(uni))"
} }
let data = key.dataUsingEncoding(NSUTF8StringEncoding) let data = key.data(usingEncoding: NSUTF8StringEncoding)
let baseKey = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) let baseKey = data?.base64EncodedString(NSDataBase64EncodingOptions(rawValue: 0))
return baseKey! return baseKey!
} }
@ -280,6 +283,8 @@ public class WebSocket : NSObject, NSStreamDelegate {
inStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String) inStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String)
outStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String) outStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String)
} }
#if swift(>=3)
#else
if let cipherSuites = self.enabledSSLCipherSuites { if let cipherSuites = self.enabledSSLCipherSuites {
if let sslContextIn = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySSLContext) as! SSLContextRef?, if let sslContextIn = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySSLContext) as! SSLContextRef?,
sslContextOut = CFWriteStreamCopyProperty(outputStream, kCFStreamPropertySSLContext) as! SSLContextRef? { sslContextOut = CFWriteStreamCopyProperty(outputStream, kCFStreamPropertySSLContext) as! SSLContextRef? {
@ -297,6 +302,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
} }
} }
} }
#endif
CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue) CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue)
CFWriteStreamSetDispatchQueue(outStream, WebSocket.sharedWorkQueue) CFWriteStreamSetDispatchQueue(outStream, WebSocket.sharedWorkQueue)
inStream.open() inStream.open()
@ -308,7 +314,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
let bytes = UnsafePointer<UInt8>(data.bytes) let bytes = UnsafePointer<UInt8>(data.bytes)
var timeout = 5000000 //wait 5 seconds before giving up var timeout = 5000000 //wait 5 seconds before giving up
writeQueue.addOperationWithBlock { [weak self] in writeQueue.addOperation { [weak self] in
while !outStream.hasSpaceAvailable { while !outStream.hasSpaceAvailable {
usleep(100) //wait until the socket is ready usleep(100) //wait until the socket is ready
timeout -= 100 timeout -= 100
@ -324,12 +330,13 @@ public class WebSocket : NSObject, NSStreamDelegate {
} }
} }
//delegate for the stream methods. Processes incoming bytes //delegate for the stream methods. Processes incoming bytes
public func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { public func stream(aStream: NSStream, handle eventCode: NSStreamEvent) {
#if swift(>=3)
#else
if let sec = security where !certValidated && [.HasBytesAvailable, .HasSpaceAvailable].contains(eventCode) { if let sec = security where !certValidated && [.HasBytesAvailable, .HasSpaceAvailable].contains(eventCode) {
let possibleTrust: AnyObject? = aStream.propertyForKey(kCFStreamPropertySSLPeerTrust as String) let possibleTrust: AnyObject? = aStream.property(forKey: kCFStreamPropertySSLPeerTrust as String)
if let trust: AnyObject = possibleTrust { if let trust: AnyObject = possibleTrust {
let domain: AnyObject? = aStream.propertyForKey(kCFStreamSSLPeerName as String) let domain: AnyObject? = aStream.property(forKey: kCFStreamSSLPeerName as String)
if sec.isValid(trust as! SecTrustRef, domain: domain as! String?) { if sec.isValid(trust as! SecTrustRef, domain: domain as! String?) {
certValidated = true certValidated = true
} else { } else {
@ -339,13 +346,14 @@ public class WebSocket : NSObject, NSStreamDelegate {
} }
} }
} }
if eventCode == .HasBytesAvailable { #endif
if eventCode == .hasBytesAvailable {
if aStream == inputStream { if aStream == inputStream {
processInputStream() processInputStream()
} }
} else if eventCode == .ErrorOccurred { } else if eventCode == .errorOccurred {
disconnectStream(aStream.streamError) disconnectStream(aStream.streamError)
} else if eventCode == .EndEncountered { } else if eventCode == .endEncountered {
disconnectStream(nil) disconnectStream(nil)
} }
} }
@ -399,7 +407,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
var work = data var work = data
if let fragBuffer = fragBuffer { if let fragBuffer = fragBuffer {
let combine = NSMutableData(data: fragBuffer) let combine = NSMutableData(data: fragBuffer)
combine.appendData(data) combine.append(data)
work = combine work = combine
self.fragBuffer = nil self.fragBuffer = nil
} }
@ -525,7 +533,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
extra = 0 extra = 0
} }
response.bytesLeft -= len response.bytesLeft -= len
response.buffer?.appendData(NSData(bytes: buffer, length: len)) response.buffer?.append(NSData(bytes: buffer, length: len))
processResponse(response) processResponse(response)
let offset = bufferLen - extra let offset = bufferLen - extra
if extra > 0 { if extra > 0 {
@ -659,7 +667,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
writeError(errCode) writeError(errCode)
return return
} }
response!.buffer!.appendData(data) response!.buffer!.append(data)
} }
if let response = response { if let response = response {
response.bytesLeft -= Int(len) response.bytesLeft -= Int(len)
@ -740,7 +748,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
} }
///used to write things to the stream ///used to write things to the stream
private func dequeueWrite(data: NSData, code: OpCode) { private func dequeueWrite(data: NSData, code: OpCode) {
writeQueue.addOperationWithBlock { [weak self] in writeQueue.addOperation { [weak self] in
//stream isn't ready, let's wait //stream isn't ready, let's wait
guard let s = self else { return } guard let s = self else { return }
var offset = 2 var offset = 2
@ -817,6 +825,8 @@ public class WebSocket : NSObject, NSStreamDelegate {
} }
#if swift(>=3)
#else
public class SSLCert { public class SSLCert {
var certData: NSData? var certData: NSData?
var key: SecKeyRef? var key: SecKeyRef?
@ -1049,4 +1059,5 @@ public class SSLSecurity {
} }
} }
#endif