merge master

This commit is contained in:
Erik 2015-03-22 15:10:12 -04:00
commit 1d70305743
7 changed files with 178 additions and 302 deletions

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "Socket.IO-Client-Swift" s.name = "Socket.IO-Client-Swift"
s.version = "1.3.2" s.version = "1.3.3"
s.summary = "Socket.IO-client for Swift" s.summary = "Socket.IO-client for Swift"
s.description = <<-DESC s.description = <<-DESC
Socket.IO-client for Swift. Socket.IO-client for Swift.
@ -12,7 +12,7 @@ Pod::Spec.new do |s|
s.author = { "Erik" => "nuclear.ace@gmail.com" } s.author = { "Erik" => "nuclear.ace@gmail.com" }
s.ios.deployment_target = '8.0' s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.10' s.osx.deployment_target = '10.10'
s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v1.3.2' } s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v1.3.3' }
s.source_files = "SwiftIO/**/*.swift" s.source_files = "SwiftIO/**/*.swift"
s.requires_arc = true s.requires_arc = true
# s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files # s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files

View File

@ -30,7 +30,7 @@ extension String {
} }
} }
private typealias Probe = (msg:String, type:PacketType, data:[NSData]?) private typealias Probe = (msg:String, type:PacketType, data:ContiguousArray<NSData>?)
private typealias ProbeWaitQueue = [Probe] private typealias ProbeWaitQueue = [Probe]
public enum PacketType: String { public enum PacketType: String {
@ -476,10 +476,8 @@ public class SocketEngine: NSObject, WebSocketDelegate {
} }
} }
/* /// Send an engine message (4)
Send a message with type 4 public func send(msg:String, withData datas:ContiguousArray<NSData>?) {
*/
public func send(msg:String, withData datas:[NSData]?) {
if self.probing { if self.probing {
self.probeWait.append((msg, PacketType.MESSAGE, datas)) self.probeWait.append((msg, PacketType.MESSAGE, datas))
} else { } else {
@ -496,9 +494,8 @@ public class SocketEngine: NSObject, WebSocketDelegate {
} }
private func sendPollMessage(var msg:String, withType type:PacketType, private func sendPollMessage(var msg:String, withType type:PacketType,
datas:[NSData]? = nil) { datas:ContiguousArray<NSData>? = nil) {
// println("Sending poll: \(msg) as type: \(type.rawValue)") // println("Sending poll: \(msg) as type: \(type.rawValue)")
doubleEncodeUTF8(&msg) doubleEncodeUTF8(&msg)
let strMsg = "\(type.rawValue)\(msg)" let strMsg = "\(type.rawValue)\(msg)"
@ -517,18 +514,19 @@ public class SocketEngine: NSObject, WebSocketDelegate {
} }
} }
private func sendWebSocketMessage(str:String, withType type:PacketType, datas:[NSData]? = nil) { private func sendWebSocketMessage(str:String, withType type:PacketType,
// println("Sending ws: \(str) as type: \(type.rawValue)") datas:ContiguousArray<NSData>? = nil) {
self.ws?.writeString("\(type.rawValue)\(str)") // println("Sending ws: \(str) as type: \(type.rawValue)")
self.ws?.writeString("\(type.rawValue)\(str)")
if datas != nil { if datas != nil {
for data in datas! { for data in datas! {
let (data, nilString) = self.createBinaryDataForSend(data) let (data, nilString) = self.createBinaryDataForSend(data)
if data != nil { if data != nil {
self.ws?.writeData(data!) self.ws?.writeData(data!)
}
} }
} }
}
} }
// Starts the ping timer // Starts the ping timer
@ -554,7 +552,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
} }
} }
public func write(msg:String, withType type:PacketType, withData data:[NSData]?) { public func write(msg:String, withType type:PacketType, withData data:ContiguousArray<NSData>?) {
dispatch_async(self.emitQueue) {[weak self] in dispatch_async(self.emitQueue) {[weak self] in
if self == nil { if self == nil {
return return
@ -565,10 +563,10 @@ public class SocketEngine: NSObject, WebSocketDelegate {
} }
if self!.websocket { if self!.websocket {
// NSLog("writing ws: \(msg):\(datas)") // NSLog("writing ws: \(msg):\(data)")
self?.sendWebSocketMessage(msg, withType: type, datas: data) self?.sendWebSocketMessage(msg, withType: type, datas: data)
} else { } else {
// NSLog("writing poll: \(msg):\(datas)") // NSLog("writing poll: \(msg):\(data)")
self?.sendPollMessage(msg, withType: type, datas: data) self?.sendPollMessage(msg, withType: type, datas: data)
} }
} }

View File

@ -26,7 +26,6 @@
import Foundation import Foundation
@objc public protocol SocketEngineClient { @objc public protocol SocketEngineClient {
var ackQueue:dispatch_queue_attr_t! {get}
var handleQueue:dispatch_queue_attr_t! {get} var handleQueue:dispatch_queue_attr_t! {get}
var emitQueue:dispatch_queue_attr_t! {get} var emitQueue:dispatch_queue_attr_t! {get}
var reconnecting:Bool {get} var reconnecting:Bool {get}
@ -38,4 +37,4 @@ import Foundation
func pollingDidFail(err:NSError) func pollingDidFail(err:NSError)
func webSocketDidCloseWithCode(code:Int, reason:String, wasClean:Bool) func webSocketDidCloseWithCode(code:Int, reason:String, wasClean:Bool)
func webSocketDidFailWithError(error:NSError) func webSocketDidFailWithError(error:NSError)
} }

View File

@ -28,10 +28,10 @@ public typealias NormalCallback = (NSArray?, AckEmitter?) -> Void
public typealias AnyHandler = (event:String, items:AnyObject?) public typealias AnyHandler = (event:String, items:AnyObject?)
public typealias AckEmitter = (AnyObject...) -> Void public typealias AckEmitter = (AnyObject...) -> Void
private func emitAckCallback(socket:SocketIOClient, num:Int, type:Int) private func emitAckCallback(socket:SocketIOClient, num:Int)
// Curried // Curried
(items:AnyObject...) -> Void { (items:AnyObject...) -> Void {
socket.emitAck(num, withData: items, withAckType: type) socket.emitAck(num, withData: items)
} }
class SocketEventHandler { class SocketEventHandler {
@ -46,7 +46,7 @@ class SocketEventHandler {
func executeCallback(_ items:NSArray? = nil, withAck ack:Int? = nil, withAckType type:Int? = nil, func executeCallback(_ items:NSArray? = nil, withAck ack:Int? = nil, withAckType type:Int? = nil,
withSocket socket:SocketIOClient? = nil) { withSocket socket:SocketIOClient? = nil) {
dispatch_async(dispatch_get_main_queue()) {[weak self] in dispatch_async(dispatch_get_main_queue()) {[weak self] in
self?.callback?(items, ack != nil ? emitAckCallback(socket!, ack!, type!) : nil) self?.callback?(items, ack != nil ? emitAckCallback(socket!, ack!) : nil)
return return
} }
} }

View File

@ -27,26 +27,24 @@ import Foundation
public class SocketIOClient: NSObject, SocketEngineClient { public class SocketIOClient: NSObject, SocketEngineClient {
let reconnectAttempts:Int! let reconnectAttempts:Int!
private lazy var params = [String: AnyObject]() private lazy var params = [String: AnyObject]()
private var ackHandlers = [SocketAckHandler]() private var ackHandlers = ContiguousArray<SocketAckHandler>()
private var anyHandler:((AnyHandler) -> Void)? private var anyHandler:((AnyHandler) -> Void)?
private var _closed = false private var _closed = false
private var _connected = false private var _connected = false
private var _connecting = false private var _connecting = false
private var currentReconnectAttempt = 0 private var currentReconnectAttempt = 0
private var forcePolling = false private var forcePolling = false
private var handlers = [SocketEventHandler]() private var handlers = ContiguousArray<SocketEventHandler>()
private var paramConnect = false private var paramConnect = false
private var _secure = false private var _secure = false
private var _sid:String? private var _sid:String?
private var _reconnecting = false private var _reconnecting = false
private var reconnectTimer:NSTimer? private var reconnectTimer:NSTimer?
internal var currentAck = -1 var currentAck = -1
internal var waitingData = [SocketPacket]() var waitingData = ContiguousArray<SocketPacket>()
public let socketURL:String public let socketURL:String
public let ackQueue = dispatch_queue_create("ackQueue".cStringUsingEncoding(NSUTF8StringEncoding),
DISPATCH_QUEUE_SERIAL)
public let handleQueue = dispatch_queue_create("handleQueue".cStringUsingEncoding(NSUTF8StringEncoding), public let handleQueue = dispatch_queue_create("handleQueue".cStringUsingEncoding(NSUTF8StringEncoding),
DISPATCH_QUEUE_SERIAL) DISPATCH_QUEUE_SERIAL)
public let emitQueue = dispatch_queue_create("emitQueue".cStringUsingEncoding(NSUTF8StringEncoding), public let emitQueue = dispatch_queue_create("emitQueue".cStringUsingEncoding(NSUTF8StringEncoding),
@ -62,7 +60,7 @@ public class SocketIOClient: NSObject, SocketEngineClient {
} }
public var cookies:[NSHTTPCookie]? public var cookies:[NSHTTPCookie]?
public var engine:SocketEngine? public var engine:SocketEngine?
public var nsp:String? public var nsp = "/"
public var reconnects = true public var reconnects = true
public var reconnecting:Bool { public var reconnecting:Bool {
return self._reconnecting return self._reconnecting
@ -244,69 +242,40 @@ public class SocketIOClient: NSObject, SocketEngineClient {
} }
private func _emit(event:String, _ args:[AnyObject], ack:Int? = nil) { private func _emit(event:String, _ args:[AnyObject], ack:Int? = nil) {
var frame:SocketPacket
var str:String
let (items, hasBinary, emitDatas) = SocketParser.parseEmitArgs(args)
if !self.connected { if !self.connected {
return return
} }
if hasBinary { let packet = SocketPacket(type: nil, data: args, nsp: self.nsp, id: ack)
if ack == nil { var str:String
str = SocketPacket.createMessageForEvent(event, withArgs: items,
hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp) SocketParser.parseForEmit(packet)
} else { str = packet.createMessageForEvent(event)
str = SocketPacket.createMessageForEvent(event, withArgs: items,
hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp, wantsAck: ack) if packet.type == SocketPacketType.BINARY_EVENT {
} self.engine?.send(str, withData: packet.binary)
self.engine?.send(str, withData: emitDatas)
} else { } else {
if ack == nil {
str = SocketPacket.createMessageForEvent(event, withArgs: items, hasBinary: false,
withDatas: 0, toNamespace: self.nsp)
} else {
str = SocketPacket.createMessageForEvent(event, withArgs: items, hasBinary: false,
withDatas: 0, toNamespace: self.nsp, wantsAck: ack)
}
self.engine?.send(str, withData: nil) self.engine?.send(str, withData: nil)
} }
} }
// If the server wants to know that the client received data // If the server wants to know that the client received data
func emitAck(ack:Int, withData data:[AnyObject]?, withAckType ackType:Int) { func emitAck(ack:Int, withData args:[AnyObject]) {
dispatch_async(self.ackQueue) {[weak self] in dispatch_async(self.emitQueue) {[weak self] in
if self == nil || !self!.connected || data == nil { if self == nil || !self!.connected {
return return
} }
// println("sending ack: \(ack) \(data)") let packet = SocketPacket(type: nil, data: args, nsp: self!.nsp, id: ack)
let (items, hasBinary, emitDatas) = SocketParser.parseEmitArgs(data!)
var str:String var str:String
if !hasBinary { SocketParser.parseForEmit(packet)
if self?.nsp == nil { str = packet.createAck()
str = SocketPacket.createAck(ack, withArgs: items,
withAckType: 3, withNsp: "/") if packet.type == SocketPacketType.BINARY_ACK {
} else { self?.engine?.send(str, withData: packet.binary)
str = SocketPacket.createAck(ack, withArgs: items,
withAckType: 3, withNsp: self!.nsp!)
}
self?.engine?.send(str, withData: nil)
} else { } else {
if self?.nsp == nil { self?.engine?.send(str, withData: nil)
str = SocketPacket.createAck(ack, withArgs: items,
withAckType: 6, withNsp: "/", withBinary: emitDatas.count)
} else {
str = SocketPacket.createAck(ack, withArgs: items,
withAckType: 6, withNsp: self!.nsp!, withBinary: emitDatas.count)
}
self?.engine?.send(str, withData: emitDatas)
} }
} }
} }
@ -361,8 +330,8 @@ public class SocketIOClient: NSObject, SocketEngineClient {
// Should be removed and moved to SocketEngine // Should be removed and moved to SocketEngine
func joinNamespace() { func joinNamespace() {
if self.nsp != nil { if self.nsp != "/" {
self.engine?.send("0/\(self.nsp!)", withData: nil) self.engine?.send("0/\(self.nsp)", withData: nil)
} }
} }

View File

@ -43,16 +43,16 @@ enum SocketPacketType: Int {
} }
class SocketPacket { class SocketPacket {
let type:SocketPacketType var binary = ContiguousArray<NSData>()
var binary = [NSData]()
var currentPlace = 0 var currentPlace = 0
var data:[AnyObject]? var data:[AnyObject]?
var id:Int? var id:Int?
var justAck = false var justAck = false
var nsp = "" var nsp = ""
var placeholders:Int? var placeholders:Int?
var type:SocketPacketType?
init(type:SocketPacketType, data:[AnyObject]? = nil, nsp:String = "", init(type:SocketPacketType?, data:[AnyObject]? = nil, nsp:String = "",
placeholders:Int? = nil, id:Int? = nil) { placeholders:Int? = nil, id:Int? = nil) {
self.type = type self.type = type
self.data = data self.data = data
@ -61,12 +61,6 @@ class SocketPacket {
self.id = id self.id = id
} }
/// Only call if you know data is not nil
func createBinaryPlaceHolders() {
var strData = "\(self.data!)"
println(strData)
}
func getEvent() -> String { func getEvent() -> String {
return data?.removeAtIndex(0) as! String return data?.removeAtIndex(0) as! String
} }
@ -95,77 +89,77 @@ class SocketPacket {
} }
} }
class func createMessageForEvent(event:String, withArgs args:[AnyObject], func createMessageForEvent(event:String) -> String {
hasBinary:Bool, withDatas datas:Int = 0, toNamespace nsp:String?, wantsAck ack:Int? = nil) -> String {
var message:String var message:String
var jsonSendError:NSError? var jsonSendError:NSError?
if !hasBinary { if self.binary.count == 0 {
if nsp == nil { self.type = SocketPacketType.EVENT
if ack == nil {
if self.nsp == "/" {
if self.id == nil {
message = "2[\"\(event)\"" message = "2[\"\(event)\""
} else { } else {
message = "2\(ack!)[\"\(event)\"" message = "2\(self.id!)[\"\(event)\""
} }
} else { } else {
if ack == nil { if self.id == nil {
message = "2/\(nsp!),[\"\(event)\"" message = "2/\(self.nsp),[\"\(event)\""
} else { } else {
message = "2/\(nsp!),\(ack!)[\"\(event)\"" message = "2/\(self.nsp),\(self.id!)[\"\(event)\""
} }
} }
} else { } else {
if nsp == nil { self.type = SocketPacketType.BINARY_EVENT
if ack == nil {
message = "5\(datas)-[\"\(event)\"" if self.nsp == "/" {
if self.id == nil {
message = "5\(self.binary.count)-[\"\(event)\""
} else { } else {
message = "5\(datas)-\(ack!)[\"\(event)\"" message = "5\(self.binary.count)-\(self.id!)[\"\(event)\""
} }
} else { } else {
if ack == nil { if self.id == nil {
message = "5\(datas)-/\(nsp!),[\"\(event)\"" message = "5\(self.binary.count)-/\(self.nsp),[\"\(event)\""
} else { } else {
message = "5\(datas)-/\(nsp!),\(ack!)[\"\(event)\"" message = "5\(self.binary.count)-/\(self.nsp),\(self.id!)[\"\(event)\""
} }
} }
} }
return self.completeMessage(message, args: args) return self.completeMessage(message)
} }
class func createAck(ack:Int, withArgs args:[AnyObject], withAckType ackType:Int, func createAck() -> String {
withNsp nsp:String, withBinary binary:Int = 0) -> String {
var msg:String var msg:String
if ackType == 3 { if self.binary.count == 0 {
if nsp == "/" { if nsp == "/" {
msg = "3\(ack)[" msg = "3\(self.id!)["
} else { } else {
msg = "3/\(nsp),\(ack)[" msg = "3/\(self.nsp),\(self.id!)["
} }
} else { } else {
if nsp == "/" { if nsp == "/" {
msg = "6\(binary)-\(ack)[" msg = "6\(self.binary.count)-\(self.id!)["
} else { } else {
msg = "6\(binary)-/\(nsp),\(ack)[" msg = "6\(self.binary.count)-/\(self.nsp),\(self.id!)["
} }
} }
return self.completeMessage(msg, args: args, ack: true) return self.completeMessage(msg, ack: true)
} }
private class func completeMessage(var message:String, args:[AnyObject], ack:Bool = false) -> String { func completeMessage(var message:String, ack:Bool = false) -> String {
var err:NSError? var err:NSError?
if args.count == 0 { if self.data == nil || self.data!.count == 0 {
return message + "]" return message + "]"
} else if !ack { } else if !ack {
message += "," message += ","
} }
for arg in args { for arg in self.data! {
if arg is NSDictionary || arg is [AnyObject] { if arg is NSDictionary || arg is [AnyObject] {
let jsonSend = NSJSONSerialization.dataWithJSONObject(arg, let jsonSend = NSJSONSerialization.dataWithJSONObject(arg,
options: NSJSONWritingOptions(0), error: &err) options: NSJSONWritingOptions(0), error: &err)

View File

@ -22,59 +22,114 @@
import Foundation import Foundation
private let shredder = SocketParser.PacketShredder()
class SocketParser { class SocketParser {
// Translation of socket.io-parser#deconstructPacket
private class PacketShredder {
var buf = ContiguousArray<NSData>()
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..<arr.count {
newArr[i] = shred(arr[i])
}
return newArr
} else if let dict = data as? NSDictionary {
var newDict = NSMutableDictionary(dictionary: dict)
for (key, value) in newDict {
newDict[key as NSCopying] = shred(value)
}
return newDict
} else {
return data
}
}
func deconstructPacket(packet:SocketPacket) {
if packet.data == nil {
return
}
var data = packet.data!
for i in 0..<data.count {
if data[i] is NSArray || data[i] is NSDictionary {
data[i] = shred(data[i])
} else if let bin = data[i] as? NSData {
data[i] = ["_placeholder" :true, "num": buf.count]
buf.append(bin)
}
}
packet.data = data
packet.binary = buf
buf.removeAll(keepCapacity: true)
}
}
// Translation of socket.io-client#decodeString // Translation of socket.io-client#decodeString
class func parseString(str:String) -> SocketPacket? { class func parseString(str:String) -> SocketPacket? {
let arr = Array(str) let arr = Array(str)
let type = String(arr[0]) let type = String(arr[0])
if arr.count == 1 { if arr.count == 1 {
return SocketPacket(type: SocketPacketType(str: type)) return SocketPacket(type: SocketPacketType(str: type))
} }
var id = nil as Int? var id = nil as Int?
var nsp = "" var nsp = ""
var i = 0 var i = 0
var placeholders = -1 var placeholders = -1
if type == "5" || type == "6" { if type == "5" || type == "6" {
var buf = "" var buf = ""
while arr[++i] != "-" { while arr[++i] != "-" {
buf += String(arr[i]) buf += String(arr[i])
if i == arr.count { if i == arr.count {
break break
} }
} }
if buf.toInt() == nil || arr[i] != "-" { if buf.toInt() == nil || arr[i] != "-" {
println(buf)
NSLog("Error parsing \(str)") NSLog("Error parsing \(str)")
return nil return nil
} else { } else {
placeholders = buf.toInt()! placeholders = buf.toInt()!
} }
} }
if arr[i + 1] == "/" { if arr[i + 1] == "/" {
while ++i < arr.count { while ++i < arr.count {
let c = arr[i] let c = arr[i]
if c == "," { if c == "," {
break break
} }
nsp += String(c) nsp += String(c)
} }
} }
if i + 1 >= arr.count { if i + 1 >= arr.count {
return SocketPacket(type: SocketPacketType(str: type), return SocketPacket(type: SocketPacketType(str: type),
nsp: nsp, placeholders: placeholders, id: id) nsp: nsp, placeholders: placeholders, id: id)
} }
let next = String(arr[i + 1]) let next = String(arr[i + 1])
if next.toInt() != nil { if next.toInt() != nil {
var c = "" var c = ""
while ++i < arr.count { while ++i < arr.count {
@ -85,226 +140,87 @@ class SocketParser {
break break
} }
} }
id = c.toInt() id = c.toInt()
} }
if i + 1 < arr.count { if i + 1 < arr.count {
let d = String(arr[++i...arr.count-1]) let d = String(arr[++i...arr.count-1])
let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" 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, return SocketPacket(type: SocketPacketType(str: type), data: data,
nsp: nsp, placeholders: placeholders, id: id) nsp: nsp, placeholders: placeholders, id: id)
} }
return nil return nil
} }
// Parse an NSArray looking for binary data
class func parseArray(arr:NSArray, var currentPlaceholder:Int) -> (NSArray, Bool, [NSData]) {
var replacementArr = [AnyObject](count: arr.count, repeatedValue: 1)
var hasBinary = false
var arrayDatas = [NSData]()
for g in 0..<arr.count {
if arr[g] is NSData {
hasBinary = true
currentPlaceholder++
let sendData = arr[g] as! NSData
arrayDatas.append(sendData)
replacementArr[g] = ["_placeholder": true,
"num": currentPlaceholder]
} else if let dict = arr[g] as? NSDictionary {
let (nestDict, hadBinary, dictArrs) = self.parseNSDictionary(dict,
currentPlaceholder: currentPlaceholder)
if hadBinary {
hasBinary = true
currentPlaceholder += dictArrs.count
replacementArr[g] = nestDict
arrayDatas.extend(dictArrs)
} else {
replacementArr[g] = dict
}
} else if let nestArr = arr[g] as? NSArray {
// Recursive
let (nested, hadBinary, nestDatas) = self.parseArray(nestArr,
currentPlaceholder: currentPlaceholder)
if hadBinary {
hasBinary = true
currentPlaceholder += nestDatas.count
replacementArr[g] = nested
arrayDatas.extend(nestDatas)
} else {
replacementArr[g] = arr[g]
}
} else {
replacementArr[g] = arr[g]
}
}
return (replacementArr, hasBinary, arrayDatas)
}
// Parses data for events // Parses data for events
class func parseData(data:String) -> AnyObject? { class func parseData(data:String) -> AnyObject? {
var err:NSError? var err:NSError?
let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!, let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!,
options: NSJSONReadingOptions.AllowFragments, error: &err) options: NSJSONReadingOptions.AllowFragments, error: &err)
if err != nil { if err != nil {
// println(err) // println(err)
return nil return nil
} }
return parsed return parsed
} }
class func parseEmitArgs(args:[AnyObject]) -> ([AnyObject], Bool, [NSData]) { class func parseForEmit(packet:SocketPacket) {
var items = [AnyObject](count: args.count, repeatedValue: 1) shredder.deconstructPacket(packet)
var currentPlaceholder = -1
var hasBinary = false
var emitDatas = [NSData]()
for i in 0..<args.count {
if let dict = args[i] as? NSDictionary {
// Check for binary data
let (newDict, hadBinary, binaryDatas) = self.parseNSDictionary(dict,
currentPlaceholder: currentPlaceholder)
if hadBinary {
currentPlaceholder += binaryDatas.count
emitDatas.extend(binaryDatas)
hasBinary = true
items[i] = newDict
} else {
items[i] = dict
}
} else if let arr = args[i] as? NSArray {
// arg is array, check for binary
let (replace, hadData, newDatas) = self.parseArray(arr,
currentPlaceholder: currentPlaceholder)
if hadData {
hasBinary = true
currentPlaceholder += newDatas.count
for data in newDatas {
emitDatas.append(data)
}
items[i] = replace
} else {
items[i] = arr
}
} else if let binaryData = args[i] as? NSData {
// args is just binary
hasBinary = true
currentPlaceholder++
items[i] = ["_placeholder": true, "num": currentPlaceholder]
emitDatas.append(binaryData)
} else {
items[i] = args[i]
}
}
return (items, hasBinary, emitDatas)
} }
// Parses a NSDictionary, looking for NSData objects
class func parseNSDictionary(dict:NSDictionary, var currentPlaceholder:Int) -> (NSDictionary, Bool, [NSData]) {
var returnDict = NSMutableDictionary()
var hasBinary = false
var returnDatas = [NSData]()
for (key, value) in dict {
if let binaryData = value as? NSData {
currentPlaceholder++
hasBinary = true
returnDatas.append(binaryData)
returnDict[key as! String] = ["_placeholder": true, "num": currentPlaceholder]
} else if let arr = value as? NSArray {
let (replace, hadBinary, arrDatas) = self.parseArray(arr, currentPlaceholder: currentPlaceholder)
if hadBinary {
hasBinary = true
returnDict[key as! String] = replace
currentPlaceholder += arrDatas.count
returnDatas.extend(arrDatas)
} else {
returnDict[key as! String] = arr
}
} else if let dict = value as? NSDictionary {
// Recursive
let (nestDict, hadBinary, nestDatas) = self.parseNSDictionary(dict, currentPlaceholder: currentPlaceholder)
if hadBinary {
hasBinary = true
returnDict[key as! String] = nestDict
currentPlaceholder += nestDatas.count
returnDatas.extend(nestDatas)
} else {
returnDict[key as! String] = dict
}
} else {
returnDict[key as! String] = value
}
}
return (returnDict, hasBinary, returnDatas)
}
// Parses messages recieved // Parses messages recieved
class func parseSocketMessage(var stringMessage:String, socket:SocketIOClient) { class func parseSocketMessage(stringMessage:String, socket:SocketIOClient) {
if stringMessage == "" { if stringMessage == "" {
return return
} }
func checkNSP(nsp:String) -> Bool { func checkNSP(nsp:String) -> Bool {
if nsp == "" && socket.nsp != nil { if nsp == "" && socket.nsp != "/" {
return true return true
} else { } else {
return false return false
} }
} }
var p = parseString(stringMessage) as SocketPacket! let p = parseString(stringMessage) as SocketPacket!
if p.type == SocketPacketType.EVENT { if p.type == SocketPacketType.EVENT {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
socket.handleEvent(p.getEvent(), data: p.data, isInternalMessage: false, wantsAck: p.id, withAckType: 3) socket.handleEvent(p.getEvent(), data: p.data, isInternalMessage: false, wantsAck: p.id, withAckType: 3)
} else if p.type == SocketPacketType.ACK { } else if p.type == SocketPacketType.ACK {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
socket.handleAck(p.id!, data: p.data) socket.handleAck(p.id!, data: p.data)
} else if p.type == SocketPacketType.BINARY_EVENT { } else if p.type == SocketPacketType.BINARY_EVENT {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
socket.waitingData.append(p) socket.waitingData.append(p)
} else if p.type == SocketPacketType.BINARY_ACK { } else if p.type == SocketPacketType.BINARY_ACK {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
p.justAck = true p.justAck = true
socket.waitingData.append(p) socket.waitingData.append(p)
} else if p.type == SocketPacketType.CONNECT { } else if p.type == SocketPacketType.CONNECT {
if p.nsp == "" && socket.nsp != nil { if p.nsp == "" && socket.nsp != "/" {
socket.joinNamespace() socket.joinNamespace()
} else if p.nsp != "" && socket.nsp == nil { } else if p.nsp != "" && socket.nsp == "/" {
socket.didConnect() socket.didConnect()
} else { } else {
socket.didConnect() socket.didConnect()
@ -313,25 +229,25 @@ class SocketParser {
socket.didForceClose(message: "Got Disconnect") socket.didForceClose(message: "Got Disconnect")
} }
} }
// Handles binary data // Handles binary data
class func parseBinaryData(data:NSData, socket:SocketIOClient) { class func parseBinaryData(data:NSData, socket:SocketIOClient) {
// NSLog(data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros)) // NSLog(data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros))
if socket.waitingData.count == 0 { if socket.waitingData.count == 0 {
NSLog("Got data when not remaking packet") NSLog("Got data when not remaking packet")
return return
} }
let shouldExecute = socket.waitingData[0].addData(data) let shouldExecute = socket.waitingData[0].addData(data)
if !shouldExecute { if !shouldExecute {
return return
} }
let packet = socket.waitingData.removeAtIndex(0) let packet = socket.waitingData.removeAtIndex(0)
packet.fillInPlaceholders() packet.fillInPlaceholders()
if !packet.justAck { if !packet.justAck {
socket.handleEvent(packet.getEvent(), data: packet.data, socket.handleEvent(packet.getEvent(), data: packet.data,
wantsAck: packet.id, withAckType: 6) wantsAck: packet.id, withAckType: 6)