merge master
This commit is contained in:
commit
1d70305743
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user