diff --git a/README.md b/README.md index 730fca9..cceeb6f 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! -pod 'Socket.IO-Client-Swift', '~> 1.1' +pod 'Socket.IO-Client-Swift', '~> 1.3.2' # Or latest version ``` Install pods: diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index cbb3c13..485685c 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.3.0" + s.version = "1.3.1" 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.3.0' } + s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v1.3.1' } 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/SocketEngine.swift b/SwiftIO/SocketEngine.swift index d59c2a2..46d80b4 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -30,9 +30,10 @@ extension String { } } -private typealias PollWaitQueue = [() -> Void] +private typealias Probe = (msg:String, type:PacketType, data:[NSData]?) +private typealias ProbeWaitQueue = [Probe] -private enum PacketType: String { +public enum PacketType: String { case OPEN = "0" case CLOSE = "1" case PING = "2" @@ -43,7 +44,7 @@ private enum PacketType: String { } public class SocketEngine: NSObject, WebSocketDelegate { - unowned let client:SocketIOClient + unowned let client:SocketEngineClient private let workQueue = NSOperationQueue() private let emitQueue = dispatch_queue_create( "emitQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) @@ -59,7 +60,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { private var postWait = [String]() private var _polling = true private var probing = false - private var probeWait = PollWaitQueue() + private var probeWait = ProbeWaitQueue() private var waitingForPoll = false private var waitingForPost = false private var _websocket = false @@ -80,7 +81,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { } var ws:WebSocket? - init(client:SocketIOClient, forcePolling:Bool = false, withCookies cookies:[NSHTTPCookie]?) { + init(client:SocketEngineClient, forcePolling:Bool = false, withCookies cookies:[NSHTTPCookie]?) { self.client = client self.forcePolling = forcePolling self.cookies = cookies @@ -205,7 +206,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { } for waiter in self!.probeWait { - waiter() + self?.write(waiter.msg, withType: waiter.type, withData: waiter.data) } self?.probeWait.removeAll(keepCapacity: false) @@ -477,33 +478,14 @@ public class SocketEngine: NSObject, WebSocketDelegate { } } + /* + Send a message with type 4 + */ public func send(msg:String, datas:[NSData]? = nil) { - let _send = {[weak self] (msg:String, datas:[NSData]?) -> () -> Void in - return { - if self == nil || !self!.connected { - return - } - - if self!.websocket { - // NSLog("sending ws: \(msg):\(datas)") - self?.sendWebSocketMessage(msg, withType: PacketType.MESSAGE, datas: datas) - } else { - // NSLog("sending poll: \(msg):\(datas)") - self?.sendPollMessage(msg, withType: PacketType.MESSAGE, datas: datas) - } - } - } - - dispatch_async(self.emitQueue) {[weak self] in - if self == nil { - return - } - - if self!.probing { - self?.probeWait.append(_send(msg, datas)) - } else { - _send(msg, datas)() - } + if self.probing { + self.probeWait.append((msg, PacketType.MESSAGE, datas)) + } else { + self.write(msg, withType: PacketType.MESSAGE, withData: datas) } } @@ -559,7 +541,8 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.pingTimer?.invalidate() dispatch_async(dispatch_get_main_queue()) { - self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(self.pingInterval!), target: self, + self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(self.pingInterval!), + target: self, selector: Selector("sendPing"), userInfo: nil, repeats: true) } } @@ -573,6 +556,28 @@ public class SocketEngine: NSObject, WebSocketDelegate { } } + public func write(msg:String, withType type:PacketType, withData data:[NSData]?) { + dispatch_async(self.emitQueue) {[weak self] in + if self == nil { + return + } + + if !self!.connected { + return + } + + if self!.websocket { + // NSLog("writing ws: \(msg):\(datas)") + self?.sendWebSocketMessage(msg, withType: type, datas: data) + } else { + // NSLog("writing poll: \(msg):\(datas)") + self?.sendPollMessage(msg, withType: type, datas: data) + } + } + } + + // Delagate methods + public func websocketDidConnect(socket:WebSocket) { self.websocketConnected = true self.probing = true diff --git a/SwiftIO/SocketEngineClient.swift b/SwiftIO/SocketEngineClient.swift new file mode 100644 index 0000000..22e2aab --- /dev/null +++ b/SwiftIO/SocketEngineClient.swift @@ -0,0 +1,41 @@ +// +// SocketEngineClient.swift +// Socket.IO-Swift +// +// Created by Erik Little on 3/19/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 public protocol SocketEngineClient { + var ackQueue:dispatch_queue_attr_t! {get} + var handleQueue:dispatch_queue_attr_t! {get} + var emitQueue:dispatch_queue_attr_t! {get} + var reconnecting:Bool {get} + var socketURL:String {get} + var secure:Bool {get} + + func parseSocketMessage(msg:String) + func parseBinaryData(data:NSData) + func pollingDidFail(err:NSError?) + func webSocketDidCloseWithCode(code:Int, reason:String, wasClean:Bool) + func webSocketDidFailWithError(error:NSError) +} \ No newline at end of file diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index cb67b6e..00a7119 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -24,14 +24,7 @@ import Foundation -public class SocketIOClient: NSObject { - let socketURL:String! - let ackQueue = dispatch_queue_create("ackQueue".cStringUsingEncoding(NSUTF8StringEncoding), - DISPATCH_QUEUE_SERIAL) - let handleQueue = dispatch_queue_create("handleQueue".cStringUsingEncoding(NSUTF8StringEncoding), - DISPATCH_QUEUE_SERIAL) - let emitQueue = dispatch_queue_create("emitQueue".cStringUsingEncoding(NSUTF8StringEncoding), - DISPATCH_QUEUE_SERIAL) +public class SocketIOClient: NSObject, SocketEngineClient { let reconnectAttempts:Int! private lazy var params = [String: AnyObject]() private var ackHandlers = [SocketAckHandler]() @@ -51,6 +44,13 @@ public class SocketIOClient: NSObject { internal var currentAck = -1 internal var waitingData = [SocketEvent]() + 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), + DISPATCH_QUEUE_SERIAL) + public let emitQueue = dispatch_queue_create("emitQueue".cStringUsingEncoding(NSUTF8StringEncoding), + DISPATCH_QUEUE_SERIAL) public var closed:Bool { return self._closed } @@ -379,16 +379,16 @@ public class SocketIOClient: NSObject { self.connect() } - func parseSocketMessage(msg:String) { + public func parseSocketMessage(msg:String) { SocketParser.parseSocketMessage(msg, socket: self) } - func parseBinaryData(data:NSData) { + public func parseBinaryData(data:NSData) { SocketParser.parseBinaryData(data, socket: self) } // Something happened while polling - func pollingDidFail(err:NSError?) { + public func pollingDidFail(err:NSError?) { if !self.reconnecting { self._connected = false self.handleEvent("reconnect", data: err?.localizedDescription, isInternalMessage: true) @@ -437,7 +437,7 @@ public class SocketIOClient: NSObject { } // Called when the socket is closed - func webSocketDidCloseWithCode(code:Int, reason:String!, wasClean:Bool) { + public func webSocketDidCloseWithCode(code:Int, reason:String, wasClean:Bool) { self._connected = false self._connecting = false if self.closed || !self.reconnects { @@ -449,7 +449,7 @@ public class SocketIOClient: NSObject { } // Called when an error occurs. - func webSocketDidFailWithError(error:NSError!) { + public func webSocketDidFailWithError(error:NSError) { self._connected = false self._connecting = false self.handleEvent("error", data: error.localizedDescription, isInternalMessage: true)