diff --git a/README.md b/README.md index aeed460..cf6ed0c 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:@"localhost:8 }); }]; +[socket connect]; + ``` ##Features diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index 9086555..128e147 100644 --- a/Socket.IO-Client-Swift.podspec +++ b/Socket.IO-Client-Swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Socket.IO-Client-Swift" - s.version = "1.5.1" + s.version = "2.0.0" s.summary = "Socket.IO-client for Swift" s.description = <<-DESC Socket.IO-client for Swift. @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.author = { "Erik" => "nuclear.ace@gmail.com" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.10' - s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v1.5.1' } + s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v2.0.0' } s.source_files = "SwiftIO/**/*.swift" s.requires_arc = true # s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files diff --git a/SwiftIO/SocketAckMap.swift b/SwiftIO/SocketAckMap.swift index 2a6ca81..6e7f932 100644 --- a/SwiftIO/SocketAckMap.swift +++ b/SwiftIO/SocketAckMap.swift @@ -24,9 +24,6 @@ import Foundation -public typealias AckCallback = @objc_block (NSArray?) -> Void -public typealias OnAckCallback = (timeout:UInt64, callback:AckCallback) -> Void - struct SocketAckMap { private var acks = [Int: AckCallback]() private var waiting = [Int: Bool]() diff --git a/SwiftIO/SocketEngine.swift b/SwiftIO/SocketEngine.swift index 0b228d1..e1eb0f3 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -26,24 +26,14 @@ import Foundation extension String { private var length:Int { - return countElements(self) + return count(self) } } -private typealias Probe = (msg:String, type:PacketType, data:ContiguousArray?) -private typealias ProbeWaitQueue = [Probe] - -public enum PacketType:String { - case OPEN = "0" - case CLOSE = "1" - case PING = "2" - case PONG = "3" - case MESSAGE = "4" - case UPGRADE = "5" - case NOOP = "6" -} - public class SocketEngine: NSObject, WebSocketDelegate { + private typealias Probe = (msg:String, type:PacketType, data:ContiguousArray?) + private typealias ProbeWaitQueue = [Probe] + private let workQueue = NSOperationQueue() private let emitQueue = dispatch_queue_create( "engineEmitQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) @@ -84,6 +74,24 @@ public class SocketEngine: NSObject, WebSocketDelegate { } var ws:WebSocket? + public enum PacketType:Int { + case OPEN = 0 + case CLOSE = 1 + case PING = 2 + case PONG = 3 + case MESSAGE = 4 + case UPGRADE = 5 + case NOOP = 6 + + init(str:String) { + if let value = str.toInt() { + self = PacketType(rawValue: value)! + } else { + self = PacketType.NOOP + } + } + } + public init(client:SocketEngineClient, forcePolling:Bool, forceWebsockets:Bool, withCookies cookies:[NSHTTPCookie]?) { self.client = client @@ -147,7 +155,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { urlWebSocket += "&\(keyEsc)=" if value is String { - let valueEsc = (value as String).stringByAddingPercentEncodingWithAllowedCharacters( + let valueEsc = (value as! String).stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLHostAllowedCharacterSet())! urlPolling += "\(valueEsc)" urlWebSocket += "\(valueEsc)" @@ -227,6 +235,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { } self?.waitingForPoll = false + if self!.fastUpgrade { self?.doFastUpgrade() return @@ -266,7 +275,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { var postStr = "" for packet in self.postWait { - let len = countElements(packet) + let len = count(packet) postStr += "\(len):\(packet)" } @@ -320,6 +329,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { } // A poll failed, tell the client about it + private func handlePollingFailed(reason:String) { self._connected = false self.ws?.disconnect() @@ -441,10 +451,76 @@ public class SocketEngine: NSObject, WebSocketDelegate { fixDoubleUTF8(&message) } - let type = message["^(\\d)"].groups()?[1] + let type = PacketType(str: (message["^(\\d)"].groups()?[1])!) - if type != PacketType.MESSAGE.rawValue { - // TODO Handle other packets + if type == PacketType.MESSAGE { + // Remove message type + message.removeAtIndex(message.startIndex) + + if self.client == nil { + return + } + + dispatch_async(self.client!.handleQueue) {[weak self] in + self?.client?.parseSocketMessage(message) + return + } + } else if type == PacketType.NOOP { + self.doPoll() + return + } else if type == PacketType.PONG { + // We should upgrade + if message == "3probe" { + self.upgradeTransport() + return + } + + return + } else if type == PacketType.OPEN { + var err:NSError? + + message.removeAtIndex(message.startIndex) + let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! + + if let json = NSJSONSerialization.JSONObjectWithData(mesData, + options: NSJSONReadingOptions.AllowFragments, error: &err) as? NSDictionary { + if let sid = json["sid"] as? String { + // println(json) + self.sid = sid + self._connected = true + if !self.forcePolling && !self.forceWebsockets { + self.createWebsocket(andConnect: true) + } + } else { + NSLog("Error handshaking") + return + } + + if let pingInterval = json["pingInterval"] as? Int { + self.pingInterval = pingInterval / 1000 + } + } else { + fatalError("Error parsing engine connect") + } + + self.startPingTimer() + + if !self.forceWebsockets { + self.doPoll() + } + + return + } else if type == PacketType.CLOSE { + if self.client == nil { + return + } + + if self.polling { + self.client!.engineDidForceClose("Disconnect") + } + + return + } else { if message.hasPrefix("b4") { // binary in base64 string @@ -452,91 +528,16 @@ public class SocketEngine: NSObject, WebSocketDelegate { end: advance(message.startIndex, 2))) if let data = NSData(base64EncodedString: message, - options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) { + options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) + where self.client != nil { // println("sending \(data)") - if self.client == nil { - return - } - dispatch_async(self.client!.handleQueue) {[weak self] in self?.client?.parseBinaryData(data) return } } - - return - } else if type == PacketType.NOOP.rawValue { - self.doPoll() - return - } else if type == PacketType.PONG.rawValue { - // We should upgrade - if message == "3probe" { - self.upgradeTransport() - return - } - - return - } else if type == PacketType.OPEN.rawValue { - var err:NSError? - - message.removeAtIndex(message.startIndex) - let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! - - if let json = NSJSONSerialization.JSONObjectWithData(mesData, - options: NSJSONReadingOptions.AllowFragments, error: &err) as? NSDictionary { - if let sid = json["sid"] as? String { - // println(json) - self.sid = sid - self._connected = true - if !self.forcePolling && !self.forceWebsockets { - self.createWebsocket(andConnect: true) - } - } else { - self.client?.engineDidError("Error parsing engine connect") - return - } - - if let pingInterval = json["pingInterval"] as? Int { - self.pingInterval = pingInterval / 1000 - } - } else { - self.client?.engineDidError("Error parsing engine connect") - return - } - - self.startPingTimer() - - if !self.forceWebsockets { - self.doPoll() - } - - return - } else if type == PacketType.CLOSE.rawValue { - if self.client == nil { - return - } - - if self.polling { - self.client!.engineDidForceClose("Disconnect") - } - - return } - // println("Got something idk what to do with") - // println(messageString) - } - - // Remove message type - message.removeAtIndex(message.startIndex) - - if self.client == nil { - return - } - - dispatch_async(self.client!.handleQueue) {[weak self] in - self?.client?.parseSocketMessage(message) - return } } diff --git a/SwiftIO/SocketEventHandler.swift b/SwiftIO/SocketEventHandler.swift index f68c73d..34c3086 100644 --- a/SwiftIO/SocketEventHandler.swift +++ b/SwiftIO/SocketEventHandler.swift @@ -24,9 +24,6 @@ import Foundation -public typealias NormalCallback = (NSArray?, AckEmitter?) -> Void -public typealias AckEmitter = (AnyObject...) -> Void - private func emitAckCallback(socket:SocketIOClient, num:Int) // Curried (items:AnyObject...) -> Void { diff --git a/SwiftIO/SocketFixUTF8.swift b/SwiftIO/SocketFixUTF8.swift index 032509a..5ca3ab2 100644 --- a/SwiftIO/SocketFixUTF8.swift +++ b/SwiftIO/SocketFixUTF8.swift @@ -3,6 +3,7 @@ // Socket.IO-Swift // // Created by Erik Little on 3/16/15. +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights @@ -34,4 +35,4 @@ func doubleEncodeUTF8(inout str:String) { let latin1 = str.dataUsingEncoding(NSUTF8StringEncoding)! let utf8 = NSString(data: latin1, encoding: NSISOLatin1StringEncoding)! str = utf8 as String -} \ No newline at end of file +} diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index 61988ad..0c431a2 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -195,7 +195,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { return } - self?.ackHandlers.addAck(ack, callback) + self?.ackHandlers.addAck(ack, callback: callback) dispatch_async(self!.emitQueue) { self?._emit(event, items, ack: ack) @@ -292,7 +292,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { } let packet = SocketPacket(type: nil, data: args, nsp: self.nsp, id: ack) - var str:String + let str:String SocketParser.parseForEmit(packet) str = packet.createMessageForEvent(event) @@ -312,7 +312,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { } let packet = SocketPacket(type: nil, data: args, nsp: self!.nsp, id: ack) - var str:String + let str:String SocketParser.parseForEmit(packet) str = packet.createAck() @@ -349,7 +349,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { var ackData:[AnyObject]? if data is NSArray { - ackData = data as? NSArray + ackData = (data as? [AnyObject]?)! } else if data != nil { ackData = [data!] } diff --git a/SwiftIO/SocketPacket.swift b/SwiftIO/SocketPacket.swift index 5fc9a51..9a13b5a 100644 --- a/SwiftIO/SocketPacket.swift +++ b/SwiftIO/SocketPacket.swift @@ -24,24 +24,6 @@ import Foundation -enum SocketPacketType:Int { - case CONNECT = 0 - case DISCONNECT = 1 - case EVENT = 2 - case ACK = 3 - case ERROR = 4 - case BINARY_EVENT = 5 - case BINARY_ACK = 6 - - init(str:String) { - if let int = str.toInt() { - self = SocketPacketType(rawValue: int)! - } else { - self = SocketPacketType(rawValue: 4)! - } - } -} - class SocketPacket { var binary = ContiguousArray() var currentPlace = 0 @@ -51,7 +33,7 @@ class SocketPacket { var nsp = "" var placeholders:Int? var type:SocketPacketType? - + init(type:SocketPacketType?, data:[AnyObject]? = nil, nsp:String = "", placeholders:Int? = nil, id:Int? = nil) { self.type = type @@ -60,11 +42,11 @@ class SocketPacket { self.placeholders = placeholders self.id = id } - + func getEvent() -> String { - return data?.removeAtIndex(0) as String + return data?.removeAtIndex(0) as! String } - + func addData(data:NSData) -> Bool { func checkDoEvent() -> Bool { if self.placeholders == self.currentPlace { @@ -73,14 +55,14 @@ class SocketPacket { return false } } - + if checkDoEvent() { return true } - + self.binary.append(data) self.currentPlace++ - + if checkDoEvent() { self.currentPlace = 0 return true @@ -88,14 +70,14 @@ class SocketPacket { return false } } - + func createMessageForEvent(event:String) -> String { - var message:String + let message:String var jsonSendError:NSError? - + if self.binary.count == 0 { self.type = SocketPacketType.EVENT - + if self.nsp == "/" { if self.id == nil { message = "2[\"\(event)\"" @@ -111,7 +93,7 @@ class SocketPacket { } } else { self.type = SocketPacketType.BINARY_EVENT - + if self.nsp == "/" { if self.id == nil { message = "5\(self.binary.count)-[\"\(event)\"" @@ -126,16 +108,16 @@ class SocketPacket { } } } - + return self.completeMessage(message) } - + func createAck() -> String { var msg:String - + if self.binary.count == 0 { self.type = SocketPacketType.ACK - + if nsp == "/" { msg = "3\(self.id!)[" } else { @@ -143,58 +125,57 @@ class SocketPacket { } } else { self.type = SocketPacketType.BINARY_ACK - + if nsp == "/" { msg = "6\(self.binary.count)-\(self.id!)[" } else { msg = "6\(self.binary.count)-/\(self.nsp),\(self.id!)[" } } - + return self.completeMessage(msg, ack: true) } - + func completeMessage(var message:String, ack:Bool = false) -> String { var err:NSError? - + if self.data == nil || self.data!.count == 0 { return message + "]" } else if !ack { message += "," } - + for arg in self.data! { - if arg is NSDictionary || arg is [AnyObject] { let jsonSend = NSJSONSerialization.dataWithJSONObject(arg, options: NSJSONWritingOptions(0), error: &err) let jsonString = NSString(data: jsonSend!, encoding: NSUTF8StringEncoding) - + message += jsonString! as String message += "," continue } - + if arg is String { message += "\"\(arg)\"" message += "," continue } - + message += "\(arg)" message += "," } - + if message != "" { message.removeAtIndex(message.endIndex.predecessor()) } - + return message + "]" } - + func fillInPlaceholders() { var newArr = NSMutableArray(array: self.data!) - + for i in 0.. AnyObject { if let str = data as? String { if let num = str["~~(\\d)"].groups() { @@ -217,19 +198,19 @@ class SocketPacket { } } else if let dict = data as? NSDictionary { var newDict = NSMutableDictionary(dictionary: dict) - + for (key, value) in dict { - newDict[key as NSCopying] = _fillInPlaceholders(value) + newDict[key as! NSCopying] = _fillInPlaceholders(value) } - + return newDict } else if let arr = data as? NSArray { var newArr = NSMutableArray(array: arr) - + for i in 0..() - + func shred(data:AnyObject) -> AnyObject { if let bin = data as? NSData { let placeholder = ["_placeholder" :true, "num": buf.count] - + buf.append(bin) - + return placeholder } else if let arr = data as? NSArray { var newArr = NSMutableArray(array: arr) - + for i in 0.. SocketPacket? { let arr = Array(str) let type = String(arr[0]) - + if arr.count == 1 { return SocketPacket(type: SocketPacketType(str: type)) } - + var id = nil as Int? var nsp = "" var i = 0 var placeholders = -1 - + if type == "5" || type == "6" { var buf = "" - + while arr[++i] != "-" { buf += String(arr[i]) if i == arr.count { break } } - + if buf.toInt() == nil || arr[i] != "-" { NSLog("Error parsing \(str)") return nil @@ -110,26 +110,26 @@ class SocketParser { placeholders = buf.toInt()! } } - + if arr[i + 1] == "/" { while ++i < arr.count { let c = arr[i] - + if c == "," { break } - + nsp += String(c) } } - + if i + 1 >= arr.count { return SocketPacket(type: SocketPacketType(str: type), nsp: nsp, placeholders: placeholders, id: id) } - + let next = String(arr[i + 1]) - + if next.toInt() != nil { var c = "" while ++i < arr.count { @@ -140,48 +140,48 @@ class SocketParser { break } } - + id = c.toInt() } - + if i + 1 < arr.count { let d = String(arr[++i...arr.count-1]) let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" - - let data = SocketParser.parseData(noPlaceholders) as [AnyObject] - + + let data = SocketParser.parseData(noPlaceholders) as! [AnyObject] + return SocketPacket(type: SocketPacketType(str: type), data: data, nsp: nsp, placeholders: placeholders, id: id) } - + return nil } - + // Parses data for events class func parseData(data:String) -> AnyObject? { var err:NSError? let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!, options: NSJSONReadingOptions.AllowFragments, error: &err) - + if err != nil { // println(err) return nil } - + return parsed } - + class func parseForEmit(packet:SocketPacket) { shredder.deconstructPacket(packet) } - + // Parses messages recieved class func parseSocketMessage(stringMessage:String, socket:SocketIOClient) { if stringMessage == "" { return } - + func checkNSP(nsp:String) -> Bool { if nsp == "" && socket.nsp != "/" { return true @@ -189,33 +189,33 @@ class SocketParser { return false } } - + let p = parseString(stringMessage) as SocketPacket! - + if p.type == SocketPacketType.EVENT { if checkNSP(p.nsp) { return } - + socket.handleEvent(p.getEvent(), data: p.data, isInternalMessage: false, wantsAck: p.id) } else if p.type == SocketPacketType.ACK { if checkNSP(p.nsp) { return } - + socket.handleAck(p.id!, data: p.data) } else if p.type == SocketPacketType.BINARY_EVENT { if checkNSP(p.nsp) { return } - + socket.waitingData.append(p) } else if p.type == SocketPacketType.BINARY_ACK { if checkNSP(p.nsp) { return } - + p.justAck = true socket.waitingData.append(p) } else if p.type == SocketPacketType.CONNECT { @@ -230,25 +230,25 @@ class SocketParser { socket.engineDidForceClose("Got Disconnect") } } - + // Handles binary data class func parseBinaryData(data:NSData, socket:SocketIOClient) { // NSLog(data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros)) - + if socket.waitingData.count == 0 { NSLog("Got data when not remaking packet") return } - + let shouldExecute = socket.waitingData[0].addData(data) - + if !shouldExecute { return } - + let packet = socket.waitingData.removeAtIndex(0) packet.fillInPlaceholders() - + if !packet.justAck { socket.handleEvent(packet.getEvent(), data: packet.data, wantsAck: packet.id) diff --git a/SwiftIO/SocketTypes.swift b/SwiftIO/SocketTypes.swift new file mode 100644 index 0000000..d022a93 --- /dev/null +++ b/SwiftIO/SocketTypes.swift @@ -0,0 +1,52 @@ +// +// SocketTypes.swift +// SocketIO-Swift +// +// Created by Erik Little on 4/8/15. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +// @objc_block is undocumented, but is used because Swift assumes that all +// Objective-C blocks are copied, but Objective-C assumes that Swift will copy it. +// And the way things are done here, the bridging fails to copy the block in +// SocketAckMap#addAck +public typealias AckCallback = @objc_block (NSArray?) -> Void +public typealias AckEmitter = (AnyObject...) -> Void +public typealias NormalCallback = (NSArray?, AckEmitter?) -> Void +public typealias OnAckCallback = (timeout:UInt64, callback:AckCallback) -> Void + +enum SocketPacketType:Int { + case CONNECT = 0 + case DISCONNECT = 1 + case EVENT = 2 + case ACK = 3 + case ERROR = 4 + case BINARY_EVENT = 5 + case BINARY_ACK = 6 + + init(str:String) { + if let int = str.toInt() { + self = SocketPacketType(rawValue: int)! + } else { + self = SocketPacketType(rawValue: 4)! + } + } +} \ No newline at end of file diff --git a/SwiftIO/SwiftRegex.swift b/SwiftIO/SwiftRegex.swift index 49f9524..badd5e1 100644 --- a/SwiftIO/SwiftRegex.swift +++ b/SwiftIO/SwiftRegex.swift @@ -18,7 +18,7 @@ var swiftRegexCache = [String: NSRegularExpression]() public class SwiftRegex: NSObject, BooleanType { var target:String var regex: NSRegularExpression - + init(target:String, pattern:String, options:NSRegularExpressionOptions = nil) { self.target = target if let regex = swiftRegexCache[pattern] { @@ -36,16 +36,16 @@ public class SwiftRegex: NSObject, BooleanType { } super.init() } - + class func failure(message: String) { println("SwiftRegex: "+message) //assert(false,"SwiftRegex: failed") } - + final var targetRange: NSRange { - return NSRange(location: 0,length: countElements(target.utf16)) + return NSRange(location: 0,length: count(target.utf16)) } - + final func substring(range: NSRange) -> String? { if ( range.location != NSNotFound ) { return (target as NSString).substringWithRange(range) @@ -53,23 +53,23 @@ public class SwiftRegex: NSObject, BooleanType { return nil } } - + public func doesMatch(options: NSMatchingOptions = nil) -> Bool { return range(options: options).location != NSNotFound } - + public func range(options: NSMatchingOptions = nil) -> NSRange { return regex.rangeOfFirstMatchInString(target as String, options: nil, range: targetRange) } - + public func match(options: NSMatchingOptions = nil) -> String? { return substring(range(options: options)) } - + public func groups(options: NSMatchingOptions = nil) -> [String]? { return groupsForMatch(regex.firstMatchInString(target as String, options: options, range: targetRange)) } - + func groupsForMatch(match: NSTextCheckingResult!) -> [String]? { if match != nil { var groups = [String]() @@ -85,51 +85,51 @@ public class SwiftRegex: NSObject, BooleanType { return nil } } - + public subscript(groupno: Int) -> String? { get { return groups()?[groupno] } - + set(newValue) { if newValue == nil { return } - + for match in matchResults()!.reverse() { let replacement = regex.replacementStringForResult(match, inString: target as String, offset: 0, template: newValue!) let mut = NSMutableString(string: target) mut.replaceCharactersInRange(match.rangeAtIndex(groupno), withString: replacement) - + target = mut as String } } } - + func matchResults(options: NSMatchingOptions = nil) -> [NSTextCheckingResult]? { let matches = regex.matchesInString(target as String, options: options, range: targetRange) as? [NSTextCheckingResult] - + if matches != nil { return matches! } else { return nil } } - + public func ranges(options: NSMatchingOptions = nil) -> [NSRange] { return matchResults(options: options)!.map { $0.range } } - + public func matches(options: NSMatchingOptions = nil) -> [String] { return matchResults(options: options)!.map( { self.substring($0.range)!}) } - + public func allGroups(options: NSMatchingOptions = nil) -> [[String]?] { return matchResults(options: options)!.map {self.groupsForMatch($0)} } - + public func dictionary(options: NSMatchingOptions = nil) -> Dictionary { var out = Dictionary() for match in matchResults(options: options)! { @@ -137,26 +137,26 @@ public class SwiftRegex: NSObject, BooleanType { } return out } - - func substituteMatches(substitution: (NSTextCheckingResult, UnsafeMutablePointer) -> String, + + func substituteMatches(substitution: ((NSTextCheckingResult, UnsafeMutablePointer) -> String), options:NSMatchingOptions = nil) -> String { let out = NSMutableString() var pos = 0 - + regex.enumerateMatchesInString(target as String, options: options, range: targetRange ) { (match: NSTextCheckingResult!, flags: NSMatchingFlags, stop: UnsafeMutablePointer) in - + let matchRange = match.range out.appendString( self.substring(NSRange(location:pos, length:matchRange.location-pos))!) out.appendString( substitution(match, stop) ) pos = matchRange.location + matchRange.length } - + out.appendString(substring( NSRange(location:pos, length:targetRange.length-pos))!) - + return out as String } - + public var boolValue: Bool { return doesMatch() } @@ -184,11 +184,11 @@ public func ~= (left: SwiftRegex, right: String) -> String { public func ~= (left: SwiftRegex, right: [String]) -> String { var matchNumber = 0 return left.substituteMatches({match, stop -> String in - + if ++matchNumber == right.count { stop.memory = true } - + return left.regex.replacementStringForResult( match, inString: left.target as String, offset: 0, template: right[matchNumber-1] ) }, options: nil) diff --git a/SwiftIO/WebSocket.swift b/SwiftIO/WebSocket.swift index c74e2b3..4643ce3 100644 --- a/SwiftIO/WebSocket.swift +++ b/SwiftIO/WebSocket.swift @@ -7,7 +7,6 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// import Foundation -import CoreFoundation public protocol WebSocketDelegate: class { func websocketDidConnect(socket: WebSocket) @@ -236,8 +235,8 @@ public class WebSocket : NSObject, NSStreamDelegate { } if self.selfSignedSSL { let settings: Dictionary = [kCFStreamSSLValidatesCertificateChain: NSNumber(bool:false), kCFStreamSSLPeerName: kCFNull] - inputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings) - outputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings) + inputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String) + outputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String) } isRunLoop = true inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) @@ -247,18 +246,18 @@ public class WebSocket : NSObject, NSStreamDelegate { let bytes = UnsafePointer(data.bytes) outputStream!.write(bytes, maxLength: data.length) while(isRunLoop) { - NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as NSDate) + NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as! NSDate) } } //delegate for the stream methods. Processes incoming bytes - func stream(aStream: NSStream!, handleEvent eventCode: NSStreamEvent) { + public func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { if eventCode == .HasBytesAvailable { if(aStream == inputStream) { processInputStream() } } else if eventCode == .ErrorOccurred { - disconnectStream(aStream!.streamError) + disconnectStream(aStream.streamError) } else if eventCode == .EndEncountered { disconnectStream(nil) } @@ -333,7 +332,7 @@ public class WebSocket : NSObject, NSStreamDelegate { } ///Finds the HTTP Packet in the TCP stream, by looking for the CRLF. private func processHTTP(buffer: UnsafePointer, bufferLen: Int) -> Bool { - let CRLFBytes = [UInt8("\r"), UInt8("\n"), UInt8("\r"), UInt8("\n")] + let CRLFBytes = [UInt8(ascii: "\r"), UInt8(ascii: "\n"), UInt8(ascii: "\r"), UInt8(ascii: "\n")] var k = 0 var totalSize = 0 for var i = 0; i < bufferLen; i++ { @@ -376,7 +375,7 @@ public class WebSocket : NSObject, NSStreamDelegate { } let cfHeaders = CFHTTPMessageCopyAllHeaderFields(response.takeUnretainedValue()) let headers: NSDictionary = cfHeaders.takeUnretainedValue() - let acceptKey = headers[headerWSAcceptName] as NSString + let acceptKey = headers[headerWSAcceptName] as! NSString if acceptKey.length > 0 { return true } @@ -500,7 +499,7 @@ public class WebSocket : NSObject, NSStreamDelegate { data = NSData(bytes: UnsafePointer((buffer+offset)), length: Int(len)) } if receivedOpcode == OpCode.Pong.rawValue { - let step = Int(offset+len) + let step = offset + Int(len) let extra = bufferLen-step if extra > 0 { processRawMessage((buffer+step), bufferLen: extra) @@ -565,7 +564,7 @@ public class WebSocket : NSObject, NSStreamDelegate { processResponse(response!) } - let step = Int(offset+len) + let step = offset + Int(len) let extra = bufferLen-step if(extra > 0) { processExtra((buffer+step), bufferLen: extra) @@ -597,9 +596,9 @@ public class WebSocket : NSObject, NSStreamDelegate { } dispatch_async(queue,{ if let textBlock = self.receivedTextBlock{ - textBlock(str!) + textBlock(str! as String) } - self.delegate?.websocketDidReceiveMessage(self, text: str!) + self.delegate?.websocketDidReceiveMessage(self, text: str! as String) }) } else if response.code == .BinaryFrame { let data = response.buffer! //local copy so it is perverse for writing @@ -673,7 +672,7 @@ public class WebSocket : NSObject, NSStreamDelegate { } buffer[1] |= self.MaskMask var maskKey = UnsafeMutablePointer(buffer + offset) - SecRandomCopyBytes(kSecRandomDefault, UInt(sizeof(UInt32)), maskKey) + SecRandomCopyBytes(kSecRandomDefault, Int(sizeof(UInt32)), maskKey) offset += sizeof(UInt32) for (var i = 0; i < dataLength; i++) { @@ -711,4 +710,4 @@ public class WebSocket : NSObject, NSStreamDelegate { } } -} +} \ No newline at end of file