diff --git a/README.md b/README.md index 447a32f..aeed460 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,8 @@ Methods 2. `onAny(callback:((event:String, items:AnyObject?)) -> Void)` - Adds a handler for all events. It will be called on any received event. 3. `emit(event:String, _ items:AnyObject...)` - Sends a message. Can send multiple items. 4. `emitObjc(event:String, withItems items:[AnyObject])` - `emit` for Objective-C -5. `emitWithAck(event:String, _ items:AnyObject...) -> (timeout:UInt64, callback:(NSArray?) -> Void) -> Void` - Sends a message that requests an acknowledgement from the server. Returns a function which you can use to add a handler. See example. -6. `emitWithAckObjc(event:String, withItems items:[AnyObject]) -> (UInt64, (NSArray?) -> Void) -> Void` - `emitWithAck` for Objective-C. +5. `emitWithAck(event:String, _ items:AnyObject...) -> (timeout:UInt64, callback:(NSArray?) -> Void) -> Void` - Sends a message that requests an acknowledgement from the server. Returns a function which you can use to add a handler. See example. Note: The message is not sent until you call the returned function. +6. `emitWithAckObjc(event:String, withItems items:[AnyObject]) -> (UInt64, (NSArray?) -> Void) -> Void` - `emitWithAck` for Objective-C. Note: The message is not sent until you call the returned function. 7. `connect()` - Establishes a connection to the server. A "connect" event is fired upon successful connection. 8. `connectWithParams(params:[String: AnyObject])` - Establishes a connection to the server passing the specified params. A "connect" event is fired upon successful connection. 9. `close(#fast:Bool)` - Closes the socket. Once a socket is closed it should not be reopened. Pass true to fast if you're closing from a background task. diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index 1c2d309..9086555 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.0" + s.version = "1.5.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.5.0' } + s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v1.5.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 304ddd8..435b094 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -44,7 +44,6 @@ public enum PacketType:String { } public class SocketEngine: NSObject, WebSocketDelegate { - unowned let client:SocketEngineClient private let workQueue = NSOperationQueue() private let emitQueue = dispatch_queue_create( "engineEmitQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) @@ -70,6 +69,8 @@ public class SocketEngine: NSObject, WebSocketDelegate { var connected:Bool { return self._connected } + + weak var client:SocketEngineClient? var cookies:[NSHTTPCookie]? var pingInterval:Int? var polling:Bool { @@ -97,15 +98,11 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.pingTimer?.invalidate() self.closed = true - if self.polling { - self.write("", withType: PacketType.CLOSE, withData: nil) - self.client.didForceClose("Disconnect") - } else { - self.ws?.disconnect() + self.write("", withType: PacketType.CLOSE, withData: nil) + self.ws?.disconnect() - if fast { - self.client.didForceClose("Fast Disconnect") - } + if fast || self.polling { + self.client?.didForceClose("Disconnect") } } @@ -126,11 +123,15 @@ public class SocketEngine: NSObject, WebSocketDelegate { } private func createURLs(params:[String: AnyObject]?) -> (String, String) { - var url = "\(self.client.socketURL)/socket.io/?transport=" + if self.client == nil { + return ("", "") + } + + var url = "\(self.client!.socketURL)/socket.io/?transport=" var urlPolling:String var urlWebSocket:String - if self.client.secure { + if self.client!.secure { urlPolling = "https://" + url + "polling" urlWebSocket = "wss://" + url + "websocket" } else { @@ -171,7 +172,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { } private func doFastUpgrade() { - self.sendWebSocketMessage("", withType: PacketType.UPGRADE) + if self.waitingForPoll { + NSLog("Outstanding poll when switched to websockets," + + "we'll probably disconnect soon. You should report this.") + } + + self.sendWebSocketMessage("", withType: PacketType.UPGRADE, datas: nil) self._websocket = true self._polling = false self.fastUpgrade = false @@ -204,6 +210,8 @@ public class SocketEngine: NSObject, WebSocketDelegate { } else if err != nil { if self!.polling { self?.handlePollingFailed(err.localizedDescription) + } else { + NSLog(err.localizedDescription) } return @@ -223,7 +231,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { if self!.fastUpgrade { self?.doFastUpgrade() return - } else if !self!.closed && !self!.websocket { + } else if !self!.closed && self!.polling { self?.doPoll() } }.resume() @@ -288,14 +296,14 @@ public class SocketEngine: NSObject, WebSocketDelegate { } else if err != nil && self!.polling { self?.handlePollingFailed(err.localizedDescription) return + } else if err != nil { + NSLog(err.localizedDescription) + return } self?.waitingForPost = false dispatch_async(self!.emitQueue) { - if self!.fastUpgrade { - self?.doFastUpgrade() - return - } else { + if !self!.fastUpgrade { self?.flushWaitingForPost() self?.doPoll() } @@ -321,10 +329,14 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.waitingForPoll = false self.waitingForPost = false - if !self.closed && !self.client.reconnecting { - self.client.pollingDidFail(reason) - } else if !self.client.reconnecting { - self.client.didForceClose(reason) + if self.client == nil { + return + } + + if !self.closed && !self.client!.reconnecting { + self.client?.pollingDidFail(reason) + } else if !self.client!.reconnecting { + self.client?.didForceClose(reason) } } @@ -414,8 +426,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { } private func parseEngineData(data:NSData) { - dispatch_async(self.client.handleQueue) {[weak self] in - self?.client.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1))) + if self.client == nil { + return + } + + dispatch_async(self.client!.handleQueue) {[weak self] in + self?.client?.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1))) return } } @@ -439,8 +455,13 @@ public class SocketEngine: NSObject, WebSocketDelegate { if let data = NSData(base64EncodedString: message, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) { // println("sending \(data)") - dispatch_async(self.client.handleQueue) {[weak self] in - self?.client.parseBinaryData(data) + + if self.client == nil { + return + } + + dispatch_async(self.client!.handleQueue) {[weak self] in + self?.client?.parseBinaryData(data) return } } @@ -492,8 +513,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { return } else if type == PacketType.CLOSE.rawValue { + if self.client == nil { + return + } + if self.polling { - self.client.didForceClose("Disconnect") + self.client!.didForceClose("Disconnect") } return @@ -505,8 +530,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { // Remove message type message.removeAtIndex(message.startIndex) - dispatch_async(self.client.handleQueue) {[weak self] in - self?.client.parseSocketMessage(message) + if self.client == nil { + return + } + + dispatch_async(self.client!.handleQueue) {[weak self] in + self?.client?.parseSocketMessage(message) return } } @@ -588,6 +617,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { if self.websocketConnected { // NSLog("Doing fast upgrade") // Do a fast upgrade + // At this point, we should not send anymore polling messages- self.fastUpgrade = true self.sendPollMessage("", withType: PacketType.NOOP) } @@ -628,13 +658,18 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.websocketConnected = false self.probing = false + if self.closed { + self.client?.didForceClose("Disconnect") + return + } + if self.websocket { self.pingTimer?.invalidate() self._connected = false self._websocket = false let reason = error?.localizedDescription - self.client.webSocketDidCloseWithCode(1, + self.client?.webSocketDidCloseWithCode(1, reason: reason == nil ? "Socket Disconnected" : reason!) } else { self.flushProbeWait() diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index 1621162..df1b85b 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -204,6 +204,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { if timeout != 0 { let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeout * NSEC_PER_SEC)) + dispatch_after(time, dispatch_get_main_queue()) { self?.ackHandlers.timeoutAck(ack) return