diff --git a/README.md b/README.md index b5f4dab..9e16034 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,7 @@ Constructor `init(socketURL: String, opts[String: AnyObject]? = nil)` - Constructs a new client for the given URL. opts can be omitted (will use default values.) Methods ------- -1. `socket.on(name:String, callback:((data:AnyObject?) -> Void)) -> SocketAckHandler` - Adds a handler for an event. Returns a SocketAckHandler which can be used to ack an event. See example. -2. `socket.onMultipleItems(name:String, callback:((data:NSArray?) -> Void)) -> SocketAckHandler` - Adds a handler for an event that can have multiple items. Items are stored in an array. Returns a SocketAckHandler which can be used to ack an event. See example. +1. `socket.on(name:String, callback:((data:NSArray?, ack:AckEmitter?) -> Void))` - Adds a handler for an event. Items are passed by an array. `ack` can be used to send an ack when one is requested. See example. 3. `socket.emit(event:String, args:AnyObject...)` - Sends a message. Can send multiple args. 4. `socket.emitWithAck(event:String, args:AnyObject...) -> SocketAckHandler` - Sends a message that requests an acknoweldgement from the server. Returns a SocketAckHandler which you can use to add an onAck handler. See example. 5. `socket.connect()` - Establishes a connection to the server. A "connect" event is fired upon successful connection. @@ -45,7 +44,7 @@ let socket = SocketIOClient(socketURL: "https://localhost:8080", opts: [ ]) // Socket Events -socket.on("connect") {data in +socket.on("connect") {data, ack in println("socket connected") // Sending messages @@ -60,9 +59,9 @@ socket.on("connect") {data in true, ["test": "foo"], "bar") } -// Requesting acks, and adding ack args -socket.on("ackEvent") {data in - if let str = data as? String { +// Requesting acks, and responding to acks +socket.on("ackEvent") {data, ack in + if let str = data?[0] as? String { println("Got ackEvent") } @@ -70,36 +69,37 @@ socket.on("ackEvent") {data in println(data) } -}.ackWith("I got your event", "dude") + ack?("Got your event", "dude") +} -socket.on("disconnect") {data in - if let reason = data as? String { +socket.on("disconnect") {data, ack in + if let reason = data?[0] as? String { println("Socket disconnected: \(reason)") } } -socket.on("reconnect") {data in - if let reason = data as? String { +socket.on("reconnect") {data, ack in + if let reason = data?[0] as? String { println("Socket reconnecting: \(reason)") } } -socket.on("reconnectAttempt") {data in - if let triesLeft = data as? Int { +socket.on("reconnectAttempt") {data, ack in + if let triesLeft = data?[0] as? Int { println(triesLeft) } } // End Socket Events -socket.on("jsonTest") {data in - if let json = data as? NSDictionary { +socket.on("jsonTest") {data, ack in + if let json = data?[0] as? NSDictionary { println(json["test"]!) // foo bar } } // Messages that have multiple items are passed // by an array -socket.onMultipleItems("multipleItems") {data in +socket.on("multipleItems") {data, ack in if data == nil { return } @@ -118,14 +118,14 @@ socket.onMultipleItems("multipleItems") {data in } // Recieving binary -socket.on("dataTest") {data in - if let data = data as? NSData { +socket.on("dataTest") {data, ack in + if let data = data?[0] as? NSData { println("data is binary") } } -socket.on("objectDataTest") {data in - if let dict = data as? NSDictionary { +socket.on("objectDataTest") {data, ack in + if let dict = data?[0] as? NSDictionary { if let data = dict["data"] as? NSData { let string = NSString(data: data, encoding: NSUTF8StringEncoding) println("Got data: \(string!)") diff --git a/SwiftIO/SocketAckHandler.swift b/SwiftIO/SocketAckHandler.swift index d3bfe77..5a9d909 100644 --- a/SwiftIO/SocketAckHandler.swift +++ b/SwiftIO/SocketAckHandler.swift @@ -29,7 +29,6 @@ typealias AckCallback = (AnyObject?) -> Void class SocketAckHandler { let ackNum:Int! let event:String! - var ackData:[AnyObject]? var callback:AckCallback? init(event:String, ackNum:Int = 0) { @@ -40,8 +39,4 @@ class SocketAckHandler { func onAck(callback:AckCallback) { self.callback = callback } - - func ackWith(data:AnyObject...) { - self.ackData = data - } } \ No newline at end of file diff --git a/SwiftIO/SocketEvent.swift b/SwiftIO/SocketEvent.swift index 84ee896..6019c27 100644 --- a/SwiftIO/SocketEvent.swift +++ b/SwiftIO/SocketEvent.swift @@ -104,30 +104,47 @@ class SocketEvent { return self.completeMessage(message, args: args) } - class func createAck(ack:Int, withEvent event:String, withArgs args:[AnyObject], - withAckType ackType:Int, withNsp nsp:String, withBinary binary:Int = 0) -> String { + class func createAck(ack:Int, withArgs args:[AnyObject], withAckType ackType:Int, + withNsp nsp:String, withBinary binary:Int = 0) -> String { var msg:String if ackType == 3 { if nsp == "/" { msg = "43\(ack)[" + if args.count == 0 { + println(msg + "]") + return msg + "]" + } + return self.completeMessage(msg, args: args) } else { msg = "43/\(nsp),\(ack)[" + if args.count == 0 { + return msg + "]" + } + return self.completeMessage(msg, args: args) } } else { if nsp == "/" { msg = "46\(binary)-\(ack)[" + if args.count == 0 { + return msg + "]" + } + return self.completeMessage(msg, args: args) } else { msg = "46\(binary)-/\(nsp),\(ack)[" + if args.count == 0 { + return msg + "]" + } + return self.completeMessage(msg, args: args) } } diff --git a/SwiftIO/SocketEventHandler.swift b/SwiftIO/SocketEventHandler.swift index a13add6..3fe9204 100644 --- a/SwiftIO/SocketEventHandler.swift +++ b/SwiftIO/SocketEventHandler.swift @@ -22,43 +22,28 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +typealias NormalCallback = (NSArray?, AckEmitter?) -> Void +typealias AckEmitter = (AnyObject...) -> Void + +private func emitAckCallback(socket:SocketIOClient, num:Int, type:Int) -> AckEmitter { + func emitter(items:AnyObject...) { + socket.emitAck(num, withData: items, withAckType: type) + } + + return emitter +} + class SocketEventHandler { - let ack:SocketAckHandler! let event:String! let callback:NormalCallback? - let callbackMult:MultipleCallback? - var multiEvent = false - init(event:String, callback:NormalCallback, ack:SocketAckHandler) { + init(event:String, callback:NormalCallback) { self.event = event self.callback = callback - self.callbackMult = nil - self.ack = ack } - init(event:String, callback:MultipleCallback, ack:SocketAckHandler) { - self.event = event - self.callbackMult = callback - self.callback = nil - self.multiEvent = true - self.ack = ack - } - - func executeCallback(item:AnyObject?, items:NSArray? = nil) { - if self.multiEvent { - if items != nil { - callbackMult?(items) - } else if item != nil { - callbackMult?([item!]) - } else { - callbackMult?(nil) - } - } else { - if items != nil { - callback?(items) - } else { - callback?(item) - } - } + func executeCallback(_ items:NSArray? = nil, withAck ack:Int? = nil, withAckType type:Int? = nil, + withSocket socket:SocketIOClient? = nil) { + callback?(items, ack != nil ? emitAckCallback(socket!, ack!, type!) : nil) } } \ No newline at end of file diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index de32c7f..f64e4f6 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -24,9 +24,6 @@ import Foundation -typealias NormalCallback = (AnyObject?) -> Void -typealias MultipleCallback = (NSArray?) -> Void - class SocketIOClient: NSObject, SRWebSocketDelegate { let socketURL:NSMutableString! let ackQueue = dispatch_queue_create("ackQueue".cStringUsingEncoding(NSUTF8StringEncoding), @@ -197,7 +194,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate { } // If the server wants to know that the client received data - private func emitAck(ack:Int, withEvent event:String, withData data:[AnyObject]?, withAckType ackType:Int) { + func emitAck(ack:Int, withData data:[AnyObject]?, withAckType ackType:Int) { dispatch_async(self.ackQueue) {[weak self] in if self == nil || !self!.connected || data == nil { return @@ -208,20 +205,20 @@ class SocketIOClient: NSObject, SRWebSocketDelegate { if !hasBinary { if self?.nsp == nil { - str = SocketEvent.createAck(ack, withEvent: event, withArgs: items, + str = SocketEvent.createAck(ack, withArgs: items, withAckType: 3, withNsp: "/") } else { - str = SocketEvent.createAck(ack, withEvent: event, withArgs: items, + str = SocketEvent.createAck(ack, withArgs: items, withAckType: 3, withNsp: self!.nsp!) } self?.io?.send(str) } else { if self?.nsp == nil { - str = SocketEvent.createAck(ack, withEvent: event, withArgs: items, + str = SocketEvent.createAck(ack, withArgs: items, withAckType: 6, withNsp: "/", withBinary: emitDatas.count) } else { - str = SocketEvent.createAck(ack, withEvent: event, withArgs: items, + str = SocketEvent.createAck(ack, withArgs: items, withAckType: 6, withNsp: self!.nsp!, withBinary: emitDatas.count) } @@ -255,16 +252,27 @@ class SocketIOClient: NSObject, SRWebSocketDelegate { for handler in self.handlers { if handler.event == event { if data is NSArray { - handler.executeCallback(nil, items: (data as NSArray)) if ack != nil { - self.emitAck(ack!, withEvent: event, - withData: handler.ack.ackData, withAckType: ackType) + handler.executeCallback(data as? NSArray, withAck: ack!, + withAckType: ackType, withSocket: self) + } else { + handler.executeCallback(data as? NSArray) } } else { - handler.executeCallback(data) + + // Trying to do a ternary expression in the executeCallback method + // seemed to crash Swift + var dataArr:NSArray? = nil + + if let data:AnyObject = data { + dataArr = [data] + } + if ack != nil { - self.emitAck(ack!, withEvent: event, - withData: handler.ack.ackData, withAckType: ackType) + handler.executeCallback(dataArr, withAck: ack!, + withAckType: ackType, withSocket: self) + } else { + handler.executeCallback(dataArr) } } } @@ -279,21 +287,9 @@ class SocketIOClient: NSObject, SRWebSocketDelegate { } // Adds handler for single arg message - func on(name:String, callback:NormalCallback) -> SocketAckHandler { - let ackHandler = SocketAckHandler(event: name) - let handler = SocketEventHandler(event: name, callback: callback, ack: ackHandler) + func on(name:String, callback:NormalCallback) { + let handler = SocketEventHandler(event: name, callback: callback) self.handlers.append(handler) - - return ackHandler - } - - // Adds handler for multiple arg message - func onMultipleItems(name:String, callback:MultipleCallback) -> SocketAckHandler { - let ackHandler = SocketAckHandler(event: name) - let handler = SocketEventHandler(event: name, callback: callback, ack: ackHandler) - self.handlers.append(handler) - - return ackHandler } // Opens the connection to the socket