Skip to content

Commit 51b95f9

Browse files
authored
Merge pull request #1 from socketio/master
sync
2 parents bd5c852 + 8618152 commit 51b95f9

10 files changed

+142
-127
lines changed

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Socket.IO-client for iOS/OS X.
66
##Example
77
```swift
88
import SocketIO
9+
910
let socket = SocketIOClient(socketURL: URL(string: "http://localhost:8080")!, config: [.log(true), .forcePolling(true)])
1011

1112
socket.on("connect") {data, ack in
@@ -14,7 +15,7 @@ socket.on("connect") {data, ack in
1415

1516
socket.on("currentAmount") {data, ack in
1617
if let cur = data[0] as? Double {
17-
socket.emitWithAck("canUpdate", cur)(0) {data in
18+
socket.emitWithAck("canUpdate", cur).timingOut(after: 0) {data in
1819
socket.emit("update", ["amount": cur + 2.50])
1920
}
2021

@@ -38,9 +39,9 @@ SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:url config:@{
3839
[socket on:@"currentAmount" callback:^(NSArray* data, SocketAckEmitter* ack) {
3940
double cur = [[data objectAtIndex:0] floatValue];
4041

41-
[socket emitWithAck:@"canUpdate" with:@[@(cur)]](0, ^(NSArray* data) {
42+
[[socket emitWithAck:@"canUpdate" with:@[@(cur)] timingOutAfter:0 callback:^(NSArray* data) {
4243
[socket emit:@"update" withItems:@[@{@"amount": @(cur + 2.50)}]];
43-
});
44+
}];
4445

4546
[ack with:@[@"Got your currentAmount, ", @"dude"]];
4647
}];
@@ -94,7 +95,7 @@ Carthage
9495
-----------------
9596
Add this line to your `Cartfile`:
9697
```
97-
github "socketio/socket.io-client-swift" ~> 8.0.2 # Or latest version
98+
github "socketio/socket.io-client-swift" ~> 8.1.0 # Or latest version
9899
```
99100

100101
Run `carthage update --platform ios,macosx`.
@@ -107,7 +108,7 @@ Create `Podfile` and add `pod 'Socket.IO-Client-Swift'`:
107108
use_frameworks!
108109

109110
target 'YourApp' do
110-
pod 'Socket.IO-Client-Swift', '~> 8.0.2' # Or latest version
111+
pod 'Socket.IO-Client-Swift', '~> 8.1.0' # Or latest version
111112
end
112113
```
113114

@@ -136,7 +137,7 @@ CocoaSeeds
136137
Add this line to your `Seedfile`:
137138

138139
```
139-
github "socketio/socket.io-client-swift", "v8.0.2", :files => "Source/*.swift" # Or latest version
140+
github "socketio/socket.io-client-swift", "v8.1.0", :files => "Source/*.swift" # Or latest version
140141
```
141142

142143
Run `seed install`.
@@ -182,8 +183,8 @@ Methods
182183
3. `onAny(callback:((event: String, items: AnyObject?)) -> Void)` - Adds a handler for all events. It will be called on any received event.
183184
4. `emit(_ event: String, _ items: AnyObject...)` - Sends a message. Can send multiple items.
184185
5. `emit(_ event: String, withItems items: [AnyObject])` - `emit` for Objective-C
185-
6. `emitWithAck(_ event: String, _ items: AnyObject...) -> (timeoutAfter: 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.
186-
7. `emitWithAck(_ 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.
186+
6. `emitWithAck(_ event: String, _ items: AnyObject...) -> OnAckCallback` - Sends a message that requests an acknowledgement from the server. Returns an object which you can use to add a handler. See example. Note: The message is not sent until you call timingOut(after:) on the returned object.
187+
7. `emitWithAck(_ event: String, withItems items: [AnyObject]) -> OnAckCallback` - `emitWithAck` for Objective-C. Note: The message is not sent until you call timingOutAfter on the returned object.
187188
8. `connect()` - Establishes a connection to the server. A "connect" event is fired upon successful connection.
188189
9. `connect(timeoutAfter timeoutAfter: Int, withTimeoutHandler handler: (() -> Void)?)` - Connect to the server. If it isn't connected after timeoutAfter seconds, the handler is called.
189190
10. `disconnect()` - Closes the socket. Reopening a disconnected socket is not fully tested.
@@ -205,5 +206,7 @@ Client Events
205206
##Detailed Example
206207
A more detailed example can be found [here](https://github.com/nuclearace/socket.io-client-swift-example)
207208

209+
An example using the Swift Package Manager can be found [here](https://github.com/nuclearace/socket.io-client-swift-spm-example)
210+
208211
##License
209212
MIT

Socket.IO-Client-Swift.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22
s.name = "Socket.IO-Client-Swift"
33
s.module_name = "SocketIO"
4-
s.version = "8.0.2"
4+
s.version = "8.1.0"
55
s.summary = "Socket.IO-client for iOS and OS X"
66
s.description = <<-DESC
77
Socket.IO-client for iOS and OS X.
@@ -14,7 +14,7 @@ Pod::Spec.new do |s|
1414
s.ios.deployment_target = '8.0'
1515
s.osx.deployment_target = '10.10'
1616
s.tvos.deployment_target = '9.0'
17-
s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v8.0.2' }
17+
s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v8.1.0' }
1818
s.source_files = "Source/**/*.swift"
1919
s.requires_arc = true
2020
# s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files

SocketIO-MacTests/SocketObjectiveCTest.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ @implementation SocketObjectiveCTest
2121
- (void)setUp {
2222
[super setUp];
2323
NSURL* url = [[NSURL alloc] initWithString:@"http://localhost"];
24-
self.socket = [[SocketIOClient alloc] initWithSocketURL:url config:nil];
24+
self.socket = [[SocketIOClient alloc] initWithSocketURL:url config:@{@"log": @YES, @"forcePolling": @YES}];
2525
}
2626

2727
- (void)testOnSyntax {
@@ -35,9 +35,9 @@ - (void)testEmitSyntax {
3535
}
3636

3737
- (void)testEmitWithAckSyntax {
38-
[self.socket emitWithAck:@"testAckEmit" with:@[@YES]](0, ^(NSArray* data) {
38+
[[self.socket emitWithAck:@"testAckEmit" with:@[@YES]] timingOutAfter:0 callback:^(NSArray* data) {
3939

40-
});
40+
}];
4141
}
4242

4343
- (void)testOffSyntax {

SocketIO-MacTests/SocketSideEffectTest.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ class SocketSideEffectTest: XCTestCase {
2525
}
2626

2727
func testFirstAck() {
28-
socket.emitWithAck("test")(0) {data in}
28+
socket.emitWithAck("test").timingOut(after: 0) {data in}
2929
XCTAssertEqual(socket.currentAck, 0)
3030
}
3131

3232
func testSecondAck() {
33-
socket.emitWithAck("test")(0) {data in}
34-
socket.emitWithAck("test")(0) {data in}
33+
socket.emitWithAck("test").timingOut(after: 0) {data in}
34+
socket.emitWithAck("test").timingOut(after: 0) {data in}
3535

3636
XCTAssertEqual(socket.currentAck, 1)
3737
}
3838

3939
func testHandleAck() {
4040
let expect = expectation(description: "handled ack")
41-
socket.emitWithAck("test")(0) {data in
41+
socket.emitWithAck("test").timingOut(after: 0) {data in
4242
XCTAssertEqual(data[0] as? String, "hello world")
4343
expect.fulfill()
4444
}
@@ -49,7 +49,7 @@ class SocketSideEffectTest: XCTestCase {
4949

5050
func testHandleAck2() {
5151
let expect = expectation(description: "handled ack2")
52-
socket.emitWithAck("test")(0) {data in
52+
socket.emitWithAck("test").timingOut(after: 0) {data in
5353
XCTAssertTrue(data.count == 2, "Wrong number of ack items")
5454
expect.fulfill()
5555
}

Source/SSLSecurity.swift

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// Starscream
55
//
66
// Created by Dalton Cherry on 5/16/15.
7-
// Copyright (c) 2014-2015 Dalton Cherry.
7+
// Copyright (c) 2014-2016 Dalton Cherry.
88
//
99
// Licensed under the Apache License, Version 2.0 (the "License");
1010
// you may not use this file except in compliance with the License.
@@ -19,11 +19,14 @@
1919
// limitations under the License.
2020
//
2121
//////////////////////////////////////////////////////////////////////////////////////////////////
22-
2322
import Foundation
2423
import Security
2524

26-
public class SSLCert : NSObject {
25+
public protocol SSLTrustValidator {
26+
func isValid(_ trust: SecTrust, domain: String?) -> Bool
27+
}
28+
29+
open class SSLCert {
2730
var certData: Data?
2831
var key: SecKey?
2932

@@ -50,7 +53,7 @@ public class SSLCert : NSObject {
5053
}
5154
}
5255

53-
public class SSLSecurity : NSObject {
56+
open class SSLSecurity : SSLTrustValidator {
5457
public var validatedDN = true //should the domain name be validated?
5558

5659
var isReady = false //is the key processing done?
@@ -82,16 +85,14 @@ public class SSLSecurity : NSObject {
8285
/**
8386
Designated init
8487

85-
- parameter keys: is the certificates or public keys to use
88+
- parameter certs: is the certificates or public keys to use
8689
- parameter usePublicKeys: is to specific if the publicKeys or certificates should be used for SSL pinning validation
8790

8891
- returns: a representation security object to be used with
8992
*/
9093
public init(certs: [SSLCert], usePublicKeys: Bool) {
9194
self.usePublicKeys = usePublicKeys
9295

93-
super.init()
94-
9596
if self.usePublicKeys {
9697
DispatchQueue.global(qos: .default).async {
9798
let pubKeys = certs.reduce([SecKey]()) { (pubKeys: [SecKey], cert: SSLCert) -> [SecKey] in

Source/SocketAckEmitter.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,38 @@ public final class SocketAckEmitter : NSObject {
4545
socket.emitAck(ackNum, with: items)
4646
}
4747
}
48+
49+
public final class OnAckCallback : NSObject {
50+
private let ackNumber: Int
51+
private let items: [Any]
52+
private weak var socket: SocketIOClient?
53+
54+
init(ackNumber: Int, items: [Any], socket: SocketIOClient) {
55+
self.ackNumber = ackNumber
56+
self.items = items
57+
self.socket = socket
58+
}
59+
60+
deinit {
61+
DefaultSocketLogger.Logger.log("OnAckCallback for \(ackNumber) being released", type: "OnAckCallback")
62+
}
63+
64+
public func timingOut(after seconds: Int, callback: @escaping AckCallback) {
65+
guard let socket = self.socket else { return }
66+
67+
socket.ackQueue.sync() {
68+
socket.ackHandlers.addAck(ackNumber, callback: callback)
69+
}
70+
71+
socket._emit(items, ack: ackNumber)
72+
73+
guard seconds != 0 else { return }
74+
75+
let time = DispatchTime.now() + Double(UInt64(seconds) * NSEC_PER_SEC) / Double(NSEC_PER_SEC)
76+
77+
socket.handleQueue.asyncAfter(deadline: time) {
78+
socket.ackHandlers.timeoutAck(self.ackNumber, onQueue: socket.handleQueue)
79+
}
80+
}
81+
82+
}

Source/SocketIOClient.swift

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,22 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
4646
public var reconnects = true
4747
public var reconnectWait = 10
4848

49-
private let ackQueue = DispatchQueue(label: "com.socketio.ackQueue", attributes: [])
50-
private let emitQueue = DispatchQueue(label: "com.socketio.emitQueue", attributes: [])
5149
private let logType = "SocketIOClient"
52-
private let parseQueue = DispatchQueue(label: "com.socketio.parseQueue", attributes: [])
50+
private let parseQueue = DispatchQueue(label: "com.socketio.parseQueue")
5351

5452
private var anyHandler: ((SocketAnyEvent) -> Void)?
5553
private var currentReconnectAttempt = 0
5654
private var handlers = [SocketEventHandler]()
57-
private var ackHandlers = SocketAckManager()
5855
private var reconnecting = false
5956

6057
private(set) var currentAck = -1
6158
private(set) var handleQueue = DispatchQueue.main
6259
private(set) var reconnectAttempts = -1
60+
61+
let ackQueue = DispatchQueue(label: "com.socketio.ackQueue")
62+
let emitQueue = DispatchQueue(label: "com.socketio.emitQueue")
6363

64+
var ackHandlers = SocketAckManager()
6465
var waitingPackets = [SocketPacket]()
6566

6667
public var sid: String? {
@@ -148,7 +149,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
148149

149150
guard timeoutAfter != 0 else { return }
150151

151-
let time = DispatchTime.now() + Double(Int64(timeoutAfter) * Int64(NSEC_PER_SEC)) / Double(NSEC_PER_SEC)
152+
let time = DispatchTime.now() + Double(UInt64(timeoutAfter) * NSEC_PER_SEC) / Double(NSEC_PER_SEC)
152153

153154
handleQueue.asyncAfter(deadline: time) {[weak self] in
154155
guard let this = self, this.status != .connected && this.status != .disconnected else { return }
@@ -163,24 +164,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
163164
private func createOnAck(_ items: [Any]) -> OnAckCallback {
164165
currentAck += 1
165166

166-
return {[weak self, ack = currentAck] timeout, callback in
167-
guard let this = self else { return }
168-
169-
this.ackQueue.sync() {
170-
this.ackHandlers.addAck(ack, callback: callback)
171-
}
172-
173-
174-
this._emit(items, ack: ack)
175-
176-
if timeout != 0 {
177-
let time = DispatchTime.now() + Double(Int64(timeout * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)
178-
179-
this.handleQueue.asyncAfter(deadline: time) {
180-
this.ackHandlers.timeoutAck(ack, onQueue: this.handleQueue)
181-
}
182-
}
183-
}
167+
return OnAckCallback(ackNumber: currentAck, items: items, socket: self)
184168
}
185169

186170
func didConnect() {
@@ -238,7 +222,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
238222
return createOnAck([event] + items)
239223
}
240224

241-
private func _emit(_ data: [Any], ack: Int? = nil) {
225+
func _emit(_ data: [Any], ack: Int? = nil) {
242226
emitQueue.async {
243227
guard self.status == .connected else {
244228
self.handleEvent("error", data: ["Tried emitting when not connected"], isInternalMessage: true)
@@ -269,7 +253,9 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
269253
}
270254

271255
public func engineDidClose(reason: String) {
272-
waitingPackets.removeAll()
256+
parseQueue.sync {
257+
self.waitingPackets.removeAll()
258+
}
273259

274260
if status != .disconnected {
275261
status = .notConnected

Source/SocketPacket.swift

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,18 @@ struct SocketPacket {
8787
}
8888

8989
private func completeMessage(_ message: String) -> String {
90-
let restOfMessage: String
91-
9290
if data.count == 0 {
9391
return message + "[]"
9492
}
9593

96-
do {
97-
let jsonSend = try data.toJSON()
98-
guard let jsonString = String(data: jsonSend, encoding: .utf8) else { return message + "[]" }
99-
100-
restOfMessage = jsonString
101-
} catch {
94+
guard let jsonSend = try? data.toJSON(), let jsonString = String(data: jsonSend, encoding: .utf8) else {
10295
DefaultSocketLogger.Logger.error("Error creating JSON object in SocketPacket.completeMessage",
103-
type: SocketPacket.logType)
96+
type: SocketPacket.logType)
10497

105-
restOfMessage = "[]"
98+
return message + "[]"
10699
}
107100

108-
return message + restOfMessage
101+
return message + jsonString
109102
}
110103

111104
private func createPacketString() -> String {
@@ -133,11 +126,11 @@ struct SocketPacket {
133126
// binary data
134127
private func _fillInPlaceholders(_ object: Any) -> Any {
135128
switch object {
136-
case let dict as [String: Any]:
129+
case let dict as JSON:
137130
if dict["_placeholder"] as? Bool ?? false {
138131
return binary[dict["num"] as! Int]
139132
} else {
140-
return dict.reduce([String: Any](), {cur, keyValue in
133+
return dict.reduce(JSON(), {cur, keyValue in
141134
var cur = cur
142135

143136
cur[keyValue.0] = _fillInPlaceholders(keyValue.1)
@@ -181,7 +174,7 @@ extension SocketPacket {
181174
private extension SocketPacket {
182175
// Recursive function that looks for NSData in collections
183176
static func shred(_ data: Any, binary: inout [Data]) -> Any {
184-
let placeholder = ["_placeholder": true, "num": binary.count] as [String : Any]
177+
let placeholder = ["_placeholder": true, "num": binary.count] as JSON
185178

186179
switch data {
187180
case let bin as Data:
@@ -190,8 +183,8 @@ private extension SocketPacket {
190183
return placeholder
191184
case let arr as [Any]:
192185
return arr.map({shred($0, binary: &binary)})
193-
case let dict as [String: Any]:
194-
return dict.reduce([String: Any](), {cur, keyValue in
186+
case let dict as JSON:
187+
return dict.reduce(JSON(), {cur, keyValue in
195188
var mutCur = cur
196189

197190
mutCur[keyValue.0] = shred(keyValue.1, binary: &binary)

Source/SocketTypes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ extension String : SocketData {}
4141

4242
public typealias AckCallback = ([Any]) -> Void
4343
public typealias NormalCallback = ([Any], SocketAckEmitter) -> Void
44-
public typealias OnAckCallback = (_ timeoutAfter: UInt64, _ callback: @escaping AckCallback) -> Void
4544

45+
typealias JSON = [String: Any]
4646
typealias Probe = (msg: String, type: SocketEnginePacketType, data: [Data])
4747
typealias ProbeWaitQueue = [Probe]
4848

0 commit comments

Comments
 (0)